diff --git a/LICENSE b/LICENSE index 224c847..1e9678c 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ -Copyright (c) 2012 Crealuz, Jan Willem van Diermen (jwvdiermen@crealuz.nl) +Copyright 2017 Wouter Janson 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. \ No newline at end of file +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. diff --git a/README.md b/README.md index f05260b..1ce307c 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,68 @@ -TransIP-API -=========== -Client library for the TransIP API written in C#. \ No newline at end of file +# TransIP.NET +> A client library for the TransIP API + +[![GitHub issues](https://img.shields.io/github/issues/WouterJanson/TransIP.NET.svg)](https://github.com/WouterJanson/TransIP.NET/issues) +[![license](https://img.shields.io/github/license/WouterJanson/TransIP.NET.svg)](https://github.com/WouterJanson/TransIP.NET/blob/master/LICENSE) +[![NuGet](https://img.shields.io/nuget/v/TransIP.NET.svg)](https://www.nuget.org/packages/TransIP.NET/) +[![bunq.me](https://img.shields.io/badge/bunq.me-Donate-brightgreen.svg)](https://bunq.me/wouterjanson) + +A .Net Core client library for the TransIP Api, based on the original work of jwvdiermen. + +## Installation + +NuGet: + +``` +PM> Install-Package TransIP.NET +``` + +## Usage example + +Here are some code example on how to use the TransIP.NET package, currently only the `DomainService` is supported. + +```csharp +using TransIp.Api; +using TransIp.Api.Dto; + +// +// Retrieve current DNS entries and add a record +// +var domainService = new DomainService("YourUsername", ClientMode.ReadWrite, "YourPrivateKey"); + +var info = await domainService.GetInfoAsync("example.com"); +var entries = info.DnsEntries.ToList(); +entries.Add(new DnsEntry +{ + Name = "local", + Type = DnsEntryType.A, + Expire = 3600, // 1 hour + Content = "127.0.0.1" +}); +await domainService.SetDnsEntriesAsync("example.com", entries.ToArray()); +``` + +## Release History + +* 1.1.0 + * Added `async` methods + * Added `ToString()` method for `DnsEntry` +* 1.0.0 + * Initial release + +## TODO + +* Add other services +* Re-add unit tests +* Write more example code + +## Contributing + +1. Fork it () +2. Create your feature branch (`git checkout -b feature/fooBar`) +3. Commit your changes (`git commit -am 'Add some fooBar'`) +4. Push to the branch (`git push origin feature/fooBar`) +5. Create a new Pull Request + +## Credits + +Thanks to [jwvdiermen](https://github.com/jwvdiermen/TransIP-API) for the initial version 4 years ago. diff --git a/src/TransIP-API.sln b/src/TransIP-API.sln deleted file mode 100644 index 0dd88f7..0000000 --- a/src/TransIP-API.sln +++ /dev/null @@ -1,52 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.30110.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TransIp.Api", "TransIp.Api\TransIp.Api.csproj", "{0C230541-FF71-4DDC-9AAC-213990AC4AFA}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TransIp.Api.Tests", "TransIp.Api.Tests\TransIp.Api.Tests.csproj", "{CDB1716D-C23F-4E5B-9889-F55E4C6D6F01}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{D73C8D5A-3C28-4E50-B3D5-7FD5E2984D91}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{428DAADA-F15E-41EB-A2C5-32B5A26D1DE7}" - ProjectSection(SolutionItems) = preProject - shared\ApiSettings.cs = shared\ApiSettings.cs - shared\SharedAssemblyInfo.cs = shared\SharedAssemblyInfo.cs - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TransIp.Api.Examples.DomainService", "TransIp.Api.Examples.DomainService\TransIp.Api.Examples.DomainService.csproj", "{1BEB870E-1670-4D25-81B4-C5C30BEF1A34}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{540D3B19-0E65-4F12-8895-B12F6049CD9B}" - ProjectSection(SolutionItems) = preProject - .nuget\NuGet.Config = .nuget\NuGet.Config - .nuget\NuGet.exe = .nuget\NuGet.exe - .nuget\NuGet.targets = .nuget\NuGet.targets - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {0C230541-FF71-4DDC-9AAC-213990AC4AFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0C230541-FF71-4DDC-9AAC-213990AC4AFA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0C230541-FF71-4DDC-9AAC-213990AC4AFA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0C230541-FF71-4DDC-9AAC-213990AC4AFA}.Release|Any CPU.Build.0 = Release|Any CPU - {CDB1716D-C23F-4E5B-9889-F55E4C6D6F01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CDB1716D-C23F-4E5B-9889-F55E4C6D6F01}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CDB1716D-C23F-4E5B-9889-F55E4C6D6F01}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CDB1716D-C23F-4E5B-9889-F55E4C6D6F01}.Release|Any CPU.Build.0 = Release|Any CPU - {1BEB870E-1670-4D25-81B4-C5C30BEF1A34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1BEB870E-1670-4D25-81B4-C5C30BEF1A34}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1BEB870E-1670-4D25-81B4-C5C30BEF1A34}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1BEB870E-1670-4D25-81B4-C5C30BEF1A34}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {1BEB870E-1670-4D25-81B4-C5C30BEF1A34} = {D73C8D5A-3C28-4E50-B3D5-7FD5E2984D91} - EndGlobalSection -EndGlobal diff --git a/src/TransIp.Api.Examples.DomainService/App.config b/src/TransIp.Api.Examples.DomainService/App.config deleted file mode 100644 index fad249e..0000000 --- a/src/TransIp.Api.Examples.DomainService/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/TransIp.Api.Examples.DomainService/Program.cs b/src/TransIp.Api.Examples.DomainService/Program.cs deleted file mode 100644 index f68873b..0000000 --- a/src/TransIp.Api.Examples.DomainService/Program.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System.Linq; -using TransIp.Api.Dto; -using TransIp.Api.Examples.Shared; - -namespace TransIp.Api.Examples.DomainService -{ - internal class Program - { - private static void Main(string[] args) - { - var domainService = new Api.DomainService(ApiSettings.Login, ApiSettings.Mode, ApiSettings.PrivateKey); - - //domainService.Register(new Domain - //{ - // Name = "example.com" - //}); - - // Use the code below to experiment with the API by changing values and removing the comments. - - //var whois = domainService.GetWhois("crealuz.nl"); - //whois = domainService.GetWhois("crealuz.org"); - - //var dnsEntries = new[] - //{ - // new DnsEntry { Name = "@", Expire = 86400, Type = DnsEntryType.A, Content = "127.0.0.1" }, - // new DnsEntry { Name = "www", Expire = 86400, Type = DnsEntryType.CNAME, Content = "@" } - //}; - //domainService.SetDnsEntries("my-crm.nl", dnsEntries); - - //var availability = domainService.BatchCheckAvailability(new[] - //{ - // "crealuz.nl", - // "crealuz.com", - // "crealuz.org", - // "sdfkhgdfhgsdkfhf.nl", - // "dflkjhsdguhsfsdifoj.com" - //}); - - //var tldIfnos = domainService.GetAllTldInfos(); - - //var domainNames = domainService.GetDomainNames(); - //var tldInfo = domainService.GetTldInfo("org"); - //var info = domainService.GetInfo("crealuz.org"); - //var singleAvailability = domainService.CheckAvailability("crealuz.nl"); - - //var info = domainService.GetInfo("j-cl.eu"); - //var entries = info.DnsEntries.ToList(); - //entries.Add(new DnsEntry - //{ - // Name = "local", - // Type = DnsEntryType.A, - // Expire = 3600, // 1 hour - // Content = "127.0.0.1" - //}); - //domainService.SetDnsEntries("j-cl.eu", entries.ToArray()); - } - } -} \ No newline at end of file diff --git a/src/TransIp.Api.Examples.DomainService/Properties/AssemblyInfo.cs b/src/TransIp.Api.Examples.DomainService/Properties/AssemblyInfo.cs deleted file mode 100644 index 1724606..0000000 --- a/src/TransIp.Api.Examples.DomainService/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,6 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -[assembly: AssemblyTitle("TransIp.Api.Examples.DomainService")] -[assembly: ComVisible(false)] -[assembly: Guid("bb1fff17-b616-4afb-9bdd-9058b6cecdff")] \ No newline at end of file diff --git a/src/TransIp.Api.Examples.DomainService/TransIp.Api.Examples.DomainService.csproj b/src/TransIp.Api.Examples.DomainService/TransIp.Api.Examples.DomainService.csproj deleted file mode 100644 index 28cadc8..0000000 --- a/src/TransIp.Api.Examples.DomainService/TransIp.Api.Examples.DomainService.csproj +++ /dev/null @@ -1,67 +0,0 @@ - - - - - Debug - AnyCPU - {1BEB870E-1670-4D25-81B4-C5C30BEF1A34} - Exe - Properties - TransIp.Api.Examples.DomainService - TransIp.Api.Examples.DomainService - v4.5 - 512 - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - ApiSettings.cs - - - Properties\SharedAssemblyInfo.cs - - - - - - - - - - {0c230541-ff71-4ddc-9aac-213990ac4afa} - TransIp.Api - - - - - \ No newline at end of file diff --git a/src/TransIp.Api.Tests/EncryptionHelperTest.cs b/src/TransIp.Api.Tests/EncryptionHelperTest.cs deleted file mode 100644 index 0beb404..0000000 --- a/src/TransIp.Api.Tests/EncryptionHelperTest.cs +++ /dev/null @@ -1,80 +0,0 @@ -using NUnit.Framework; -using System.Collections.Generic; -using TransIp.Api.Dto; - -namespace TransIp.Api.Tests -{ - [TestFixture] - public class EncryptionHelperTest - { - #region Data - - private static readonly string PrivateKey = - @"-----BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAzmF5dRwIDondpKnOZMIC2ew4nLlaMLvCZ3283mysD9z5Brea -YIoRvQJt725AuA8CffDX5UrUeOuaCpmXH7+QL3/tcucAVBwJ5RzKrUpmSSPIXUJQ -qXhz1MFIS6QHPtWpRnL5V2Wo9d6vgWU7PFKGqQfAJUzmtDfVsUbUM7BrT7EvWGUX -+rnJD3LixK9dWcPVy3O1nmazKJNjGALyaaTJDEwCIRMp6VyMfvG+6/XXhlYR3S03 -eq8pGXVqSqs7JbZPMVyctXf111Y+ejMqiNlZmCwfpYwlJbPu+KZsLttlEfqWDpQE -4dSDcsQlECTomu6jFS9zRrTmL2cmf8zkkVSPjQIDAQABAoIBAQCKd8Xo+ATD1GY8 -a53J5o3JLv+Qz5+eoOs/SpKk3V7YSddfVWKjsR9TpESkZ2HO3Gs8mpIQCpPiCZlR -0Vke+QVBiWCEPk7vH9zXtuiZOhjEq9hsEelSuzlkHsZl0cj2tJ4dYVi/9bpWNLGm -bIhA4dHtqQCXRjBn7CpZBf+sKorlbPSmaIKaMFjUDRAoZWCnUZ1/L7PQCmTCk/Xu -XIecsdiy5WYRQnoAyxulrtC2MVnmXeIIpDqcMwZwF/tzhSHT/H3tCEi99zgaE3dj -+2YSXfcKaESqMb+DE7yO09LnhKez1cEog3JV/PzQIEjP7JvhIICZL4bGpkP+AW51 -hHe08mcBAoGBAOr10kUQ+t4pDmB0Vnus0X9pgHfF2sXIZZDKP1P8EbtmJ8RtFBOe -/hvcwC1+EAjy+gJE5qsFz/2/2yMZIFEov5Sbmms1Qpslo6E+0w9OOWeW8xyb9dCV -7dp/gNZCxj0rVsdKOR1wgV4TicZUT3fyu8TlLscCzG4gVD6oYDYW41LNAoGBAODc -gM3+xnN/633IGl7H6CZkkyG3I343T17uyW9p9kyKOXNrRrg79XFwL4Q1GoBhuOt3 -VUPn5kY5SDyiocfnxQ/MgHVQcd4xwWq3rT9wADdC56kOMiQSL37eCkmp1KQKfrov -QuUbAu/rW4zTT76Oo0fzvncTA7fWZ9odDOztva/BAoGAKegoVcs+g2tdNhTp6+sZ -/pipojM23vnsK5P3EZqu6vbAdwdhglJkTkHkQPjwETiNIOR7I9vIiiCzDCKKIg+b -g/zw4NhCBfwDoFndOSihknlY6Sxj/o0PPF5rc0u7oeNd+fOiFj8fw9DGTQpylhlE -Jk0eN76nCalYfUh4yIzyhK0CgYB/eIEMRgH6N+onw+gvEuRn31wJIOjeBDzadEN9 -BXS6ryEibQ4KIvNg+1f0eqYrYTqTQXL0q+G+rXpl5UwRJzJvYl7wIkpqy4n6FWYB -MFzu9t6c149VI3oJUZZDbCM/WzO8GE6z0jw4BhRAIQpz3Ch0AZlXp0/UR5dX7mAF -cEC4AQKBgQCCvztBn38T1CiC4X5xS8HZe1wqPXhaBX53/wnr2APM764VSGXCsJO/ -P6e3Hd2mi4E/OCEkq3Wn76B0ruyndSHgu2NITfTUdaZiaRhmom5tcaQhrps+lomP -6YNatcJ1NRUjBEAbx6GUTdd+7kpAmfSjCp0FpgjiXW+73AHZs3M1eA== ------END RSA PRIVATE KEY-----"; - - #endregion - - [Test] - public void CanSign() - { - var domain = new Domain - { - Name = "example.com", - DnsEntries = new[] - { - new DnsEntry {Name = "@", Expire = 86400, Type = DnsEntryType.A, Content = "80.69.67.46"}, - new DnsEntry {Name = "@", Expire = 86400, Type = DnsEntryType.MX, Content = "10 @"}, - new DnsEntry {Name = "@", Expire = 86400, Type = DnsEntryType.MX, Content = "20 relay.transip.nl."}, - new DnsEntry {Name = "ftp", Expire = 86400, Type = DnsEntryType.CNAME, Content = "@"}, - new DnsEntry {Name = "mail", Expire = 86400, Type = DnsEntryType.CNAME, Content = "@"}, - new DnsEntry {Name = "www", Expire = 86400, Type = DnsEntryType.CNAME, Content = "@"} - } - }; - - const string timestamp = "1352842387"; - const string nonce = "50a2bc93d5e3e6.28404859"; - - var signature = EncryptionHelper.Encode(EncryptionHelper.Sign(PrivateKey, new object[] - { - domain, - new KeyValuePair("__method", "register"), - new KeyValuePair("__service", "DomainService"), - new KeyValuePair("__hostname", "api.transip.nl"), - new KeyValuePair("__timestamp", timestamp), - new KeyValuePair("__nonce", nonce) - })); - - // Expected signature taken from PHP example and replicated here in .NET - const string expected = - "wghhEAhMJNt4a4Rxun3oTODB4sJSvfJNYDkNqxO3PkWCkdpRrSh9MgiVCkUeAbl0zBrWf5SIXAsQSwBSrT0hoj3MyVs7XFNnod%2Finen3cLh65JCdVTS%2BRqNDqOlPzeI0AQ8tnuUXjgR%2Fr%2BxFaUJxrdirVsDt%2B4KaIurmztsY4U8%2BBLMBCS9HDoYKMJUFIGlWWHcYpNVIyg%2F8FzfXQRqDPfqOkzg%2FuXQA0%2BVF49zQewxdEYI6qLKPl8T%2BoWv%2FjgvlJZydmp378woawbngE5tQ%2FEQbOfgAHBM9i%2BwhbRFH%2FWpEy%2BJZPyhvV2sQxiDjjVFMX1A%2F9ue0rVNnjBKj86f2Rg%3D%3D"; - - Assert.AreEqual(expected, signature); - } - } -} \ No newline at end of file diff --git a/src/TransIp.Api.Tests/Properties/AssemblyInfo.cs b/src/TransIp.Api.Tests/Properties/AssemblyInfo.cs deleted file mode 100644 index d9082b4..0000000 --- a/src/TransIp.Api.Tests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,6 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -[assembly: AssemblyTitle("TransIp.Api.Tests")] -[assembly: ComVisible(false)] -[assembly: Guid("4cdf02db-8201-4c0a-9c85-78e8a5ea7488")] \ No newline at end of file diff --git a/src/TransIp.Api.Tests/TransIp.Api.Tests.csproj b/src/TransIp.Api.Tests/TransIp.Api.Tests.csproj deleted file mode 100644 index bad7786..0000000 --- a/src/TransIp.Api.Tests/TransIp.Api.Tests.csproj +++ /dev/null @@ -1,74 +0,0 @@ - - - - - Debug - AnyCPU - {CDB1716D-C23F-4E5B-9889-F55E4C6D6F01} - Library - Properties - TransIp.Api.Tests - TransIp.Api.Tests - v4.5 - 512 - ..\ - true - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - False - ..\packages\NUnit.2.6.3\lib\nunit.framework.dll - - - - - - - - Properties\SharedAssemblyInfo.cs - - - - - - - {0c230541-ff71-4ddc-9aac-213990ac4afa} - TransIp.Api - - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - \ No newline at end of file diff --git a/src/TransIp.Api.Tests/packages.config b/src/TransIp.Api.Tests/packages.config deleted file mode 100644 index d4e241a..0000000 --- a/src/TransIp.Api.Tests/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/TransIp.Api.sln b/src/TransIp.Api.sln new file mode 100644 index 0000000..c488597 --- /dev/null +++ b/src/TransIp.Api.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27130.2010 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TransIp.Api", "TransIp.Api\TransIp.Api.csproj", "{35EC4335-F4EE-44EF-BB4E-7B22E279078D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {35EC4335-F4EE-44EF-BB4E-7B22E279078D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {35EC4335-F4EE-44EF-BB4E-7B22E279078D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {35EC4335-F4EE-44EF-BB4E-7B22E279078D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {35EC4335-F4EE-44EF-BB4E-7B22E279078D}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {6961CD62-4741-4DEE-A942-3F442110A064} + EndGlobalSection +EndGlobal diff --git a/src/TransIp.Api/ClientBase.cs b/src/TransIp.Api/ClientBase.cs index 42e5242..682107e 100644 --- a/src/TransIp.Api/ClientBase.cs +++ b/src/TransIp.Api/ClientBase.cs @@ -47,16 +47,15 @@ private Binding BasicHttpBinding { get { - if (_binding == null) - { - _binding = new BasicHttpBinding - { - MaxReceivedMessageSize = int.MaxValue, - HostNameComparisonMode = HostNameComparisonMode.StrongWildcard, - AllowCookies = false - }; - _binding.Security.Mode = BasicHttpSecurityMode.Transport; + if (_binding != null) { + return _binding; } + _binding = new BasicHttpBinding + { + MaxReceivedMessageSize = int.MaxValue, + AllowCookies = false, + Security = {Mode = BasicHttpSecurityMode.Transport} + }; return _binding; } } @@ -79,7 +78,7 @@ protected ClientBase(string serviceName, string uri, string login, ClientMode mo Cookies = new CookieContainer(); Client = CreateClient(BasicHttpBinding, new EndpointAddress(_uri)); - Client.ChannelFactory.Endpoint.Behaviors.Add(new CookieEndpointBehavior(Cookies, _uri)); + Client.ChannelFactory.Endpoint.EndpointBehaviors.Add(new CookieEndpointBehavior(Cookies, _uri)); // Set the static cookies. AddCookie("login", Login); @@ -101,8 +100,7 @@ protected ClientBase(string serviceName, string uri, string login, ClientMode mo /// The passed arguments. protected void SetSignatureCookies(string method, object[] args) { - var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); - var timestamp = Convert.ToInt64((DateTime.UtcNow - epoch).TotalSeconds); + var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); var nonce = Guid.NewGuid().ToString("N"); diff --git a/src/TransIp.Api/CookieEndpointBehavior.cs b/src/TransIp.Api/CookieEndpointBehavior.cs index 1d8d67b..098d358 100644 --- a/src/TransIp.Api/CookieEndpointBehavior.cs +++ b/src/TransIp.Api/CookieEndpointBehavior.cs @@ -22,7 +22,7 @@ public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterColle public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) { - clientRuntime.MessageInspectors.Add(new CookieMessageInspector(_cookieContainer, _uri)); + clientRuntime.ClientMessageInspectors.Add(new CookieMessageInspector(_cookieContainer, _uri)); } public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) diff --git a/src/TransIp.Api/CookieMessageInspector.cs b/src/TransIp.Api/CookieMessageInspector.cs index 7c09be6..ecd4390 100644 --- a/src/TransIp.Api/CookieMessageInspector.cs +++ b/src/TransIp.Api/CookieMessageInspector.cs @@ -25,15 +25,14 @@ public CookieMessageInspector(CookieContainer cookieContainer, string uri) public void AfterReceiveReply(ref Message reply, object correlationState) { - var httpResponse = reply.Properties[HttpResponseMessageProperty.Name] as HttpResponseMessageProperty; - if (httpResponse != null) - { - var cookie = httpResponse.Headers[HttpResponseHeader.SetCookie]; - - if (!string.IsNullOrEmpty(cookie)) - { - _cookieContainer.SetCookies(new Uri(Uri), cookie); - } + if (!(reply.Properties[HttpResponseMessageProperty.Name] is HttpResponseMessageProperty httpResponse)) { + return; + } + + var cookie = httpResponse.Headers[HttpResponseHeader.SetCookie]; + + if (!string.IsNullOrEmpty(cookie)) { + _cookieContainer.SetCookies(new Uri(Uri), cookie); } } @@ -41,8 +40,7 @@ public object BeforeSendRequest(ref Message request, IClientChannel channel) { // The HTTP request object is made available in the outgoing message only when // the Visual Studio Debugger is attacched to the running process - if (!request.Properties.ContainsKey(HttpRequestMessageProperty.Name)) - { + if (!request.Properties.ContainsKey(HttpRequestMessageProperty.Name)) { request.Properties.Add(HttpRequestMessageProperty.Name, new HttpRequestMessageProperty()); } diff --git a/src/TransIp.Api/DomainService.cs b/src/TransIp.Api/DomainService.cs index c550c6b..8e6e45e 100644 --- a/src/TransIp.Api/DomainService.cs +++ b/src/TransIp.Api/DomainService.cs @@ -2,6 +2,7 @@ using System; using System.ServiceModel; using System.ServiceModel.Channels; +using System.Threading.Tasks; using TransIp.Api.Dto; using DnsEntry = TransIp.Api.Dto.DnsEntry; using Domain = TransIp.Api.Dto.Domain; @@ -24,38 +25,38 @@ public class DomainService : ClientBase static DomainService() { - Mapper.CreateMap(); - Mapper.CreateMap(); - - Mapper.CreateMap() - .ForMember(x => x.IsLocked, opt => opt.ResolveUsing(x => x.isLockedSpecified ? x.isLocked : (bool?) null)); - Mapper.CreateMap() - .ForMember(x => x.isLocked, opt => opt.ResolveUsing(x => x.IsLocked.GetValueOrDefault(false))) - .ForMember(x => x.isLockedSpecified, opt => opt.ResolveUsing(x => x.IsLocked.HasValue)); - - Mapper.CreateMap(); - Mapper.CreateMap(); - - Mapper.CreateMap(); - Mapper.CreateMap(); - - Mapper.CreateMap(); - - Mapper.CreateMap(); - Mapper.CreateMap(); - - Mapper.CreateMap() - .ForMember(x => x.CapabilityList, opt => opt.MapFrom(x => x.capabilities)) - .ForMember(x => x.Capabilities, opt => opt.Ignore()); - Mapper.CreateMap() - .ForMember(x => x.capabilities, opt => opt.MapFrom(x => x.CapabilityList)); - - Mapper.CreateMap() - .ForMember(x => x.CompanyNumber, opt => opt.MapFrom(x => x.companyKvk)); - Mapper.CreateMap() - .ForMember(x => x.companyKvk, opt => opt.MapFrom(x => x.CompanyNumber)); - - Mapper.AssertConfigurationIsValid(); + Mapper.Initialize(cfg => { + cfg.CreateMap(); + cfg.CreateMap(); + + cfg.CreateMap() + .ForMember(x => x.IsLocked, opt => opt.ResolveUsing(x => x.isLockedSpecified ? x.isLocked : (bool?)null)); + cfg.CreateMap() + .ForMember(x => x.isLocked, opt => opt.ResolveUsing(x => x.IsLocked.GetValueOrDefault(false))) + .ForMember(x => x.isLockedSpecified, opt => opt.ResolveUsing(x => x.IsLocked.HasValue)); + + cfg.CreateMap(); + cfg.CreateMap(); + + cfg.CreateMap(); + cfg.CreateMap(); + + cfg.CreateMap(); + + cfg.CreateMap(); + cfg.CreateMap(); + + cfg.CreateMap() + .ForMember(x => x.CapabilityList, opt => opt.MapFrom(x => x.capabilities)) + .ForMember(x => x.Capabilities, opt => opt.Ignore()); + cfg.CreateMap() + .ForMember(x => x.capabilities, opt => opt.MapFrom(x => x.CapabilityList)); + + cfg.CreateMap() + .ForMember(x => x.CompanyNumber, opt => opt.MapFrom(x => x.companyKvk)); + cfg.CreateMap() + .ForMember(x => x.companyKvk, opt => opt.MapFrom(x => x.CompanyNumber)); + }); } /// @@ -85,6 +86,17 @@ public DomainCheckResult[] BatchCheckAvailability(string[] domainNames) return Mapper.Map(Client.batchCheckAvailability(domainNames)); } + /// + /// Checks the availability of multiple domains. + /// + /// The domain names to check for availability. A maximum of 20 domainNames at once can be checked. + /// A list of DomainCheckResult objects, holding the domainName and the status per result. + public async Task BatchCheckAvailabilityAsync(string[] domainNames) + { + SetSignatureCookies("batchCheckAvailability", new object[] { domainNames }); + return Mapper.Map(await Client.batchCheckAvailabilityAsync(domainNames)); + } + /// /// Checks the availability of a domain. /// @@ -96,6 +108,17 @@ public AvailabilityStatus CheckAvailability(string domainName) return (AvailabilityStatus) Enum.Parse(typeof (AvailabilityStatus), Client.checkAvailability(domainName), true); } + /// + /// Checks the availability of a domain. + /// + /// The domain name to check for availability + /// The availability status of the domain name. + public async Task CheckAvailabilityAsync(string domainName) + { + SetSignatureCookies("checkAvailability", new object[] { domainName }); + return (AvailabilityStatus)Enum.Parse(typeof(AvailabilityStatus), await Client.checkAvailabilityAsync(domainName), true); + } + /// /// Gets the whois of a domain name. /// @@ -107,6 +130,17 @@ public string GetWhois(string domainName) return Client.getWhois(domainName); } + /// + /// Gets the whois of a domain name. + /// + /// The domain name to get the whois for. + /// The whois data for the domain. + public async Task GetWhoisAsync(string domainName) + { + SetSignatureCookies("getWhois", new object[] { domainName }); + return await Client.getWhoisAsync(domainName); + } + /// /// Gets the names of all domains in your account. /// @@ -117,6 +151,16 @@ public string[] GetDomainNames() return Client.getDomainNames(); } + /// + /// Gets the names of all domains in your account. + /// + /// A list of all domains in your account. + public async Task GetDomainNamesAsync() + { + SetSignatureCookies("getDomainNames", new object[0]); + return await Client.getDomainNamesAsync(); + } + /// /// Gets information about a domainName. /// @@ -128,6 +172,17 @@ public Domain GetInfo(string domainName) return Mapper.Map(Client.getInfo(domainName)); } + /// + /// Gets information about a domainName. + /// + /// The domain name to get the information for. + /// A domain object holding the data for the requested domainName. + public async Task GetInfoAsync(string domainName) + { + SetSignatureCookies("getInfo", new object[] { domainName }); + return Mapper.Map(await Client.getInfoAsync(domainName)); + } + /// /// Registers a domain name, will automatically create and sign a proposition for it. /// @@ -139,6 +194,17 @@ public void Register(Domain domain) Client.register(Mapper.Map(domain)); } + /// + /// Registers a domain name, will automatically create and sign a proposition for it. + /// + /// The domain object holding information about the domain that needs to be registered. + /// Requires "readwrite" mode. + public async Task RegisterAsync(Domain domain) + { + SetSignatureCookies("register", new object[] { domain }); + await Client.registerAsync(Mapper.Map(domain)); + } + /// /// Cancels a domain name, will automatically create and sign a cancellation document. /// Please note that domains with webhosting cannot be cancelled through the API. @@ -153,6 +219,20 @@ public void Cancel(string domainName, CancellationTime endTime) Client.cancel(domainName, endTimeStr); } + /// + /// Cancels a domain name, will automatically create and sign a cancellation document. + /// Please note that domains with webhosting cannot be cancelled through the API. + /// + /// The domain name that needs to be cancelled. + /// The time to cancel the domain. + public async Task CancelAsync(string domainName, CancellationTime endTime) + { + var endTimeStr = endTime.ToString().ToUpper(); + + SetSignatureCookies("cancel", new object[] { domainName, endTimeStr }); + await Client.cancelAsync(domainName, endTimeStr); + } + /// /// Transfers a domain with changing the owner, not all TLDs support this (e.g. nl). /// @@ -164,6 +244,17 @@ public void TransferWithOwnerChange(Domain domain, string authCode) Client.transferWithOwnerChange(Mapper.Map(domain), authCode); } + /// + /// Transfers a domain with changing the owner, not all TLDs support this (e.g. nl). + /// + /// The Domain object holding information about the domain that needs to be transfered. + /// The authorization code for domains needing this for transfers (e.g. .com or .org transfers). Leave empty when n/a. + public async Task TransferWithOwnerChangeAsync(Domain domain, string authCode) + { + SetSignatureCookies("transferWithOwnerChange", new object[] { domain, authCode }); + await Client.transferWithOwnerChangeAsync(Mapper.Map(domain), authCode); + } + /// /// Transfers a domain without changing the owner. /// @@ -175,6 +266,17 @@ public void TransferWithoutOwnerChange(Domain domain, string authCode) Client.transferWithoutOwnerChange(Mapper.Map(domain), authCode); } + /// + /// Transfers a domain without changing the owner. + /// + /// The Domain object holding information about the domain that needs to be transfered. + /// The authorization code for domains needing this for transfers (e.g. .com or .org transfers). Leave empty when n/a. + public async Task TransferWithoutOwnerChangeAsync(Domain domain, string authCode) + { + SetSignatureCookies("transferWithoutOwnerChange", new object[] { domain, authCode }); + await Client.transferWithoutOwnerChangeAsync(Mapper.Map(domain), authCode); + } + /// /// Starts a nameserver change for this domain, will replace all existing nameservers with the new nameservers. /// @@ -186,6 +288,17 @@ public void SetNameservers(string domainName, Nameserver[] nameservers) Client.setNameservers(domainName, Mapper.Map(nameservers)); } + /// + /// Starts a nameserver change for this domain, will replace all existing nameservers with the new nameservers. + /// + /// The domain name to change the nameservers for. + /// The list of new nameservers for this domain. + public async Task SetNameserversAsync(string domainName, Nameserver[] nameservers) + { + SetSignatureCookies("setNameservers", new object[] { domainName, nameservers }); + await Client.setNameserversAsync(domainName, Mapper.Map(nameservers)); + } + /// /// Lock this domain in real time. /// @@ -196,6 +309,16 @@ public void SetLock(string domainName) Client.setLock(domainName); } + /// + /// Lock this domain in real time. + /// + /// The domain name to set the lock for. + public async Task SetLockAsync(string domainName) + { + SetSignatureCookies("setLock", new object[] { domainName }); + await Client.setLockAsync(domainName); + } + /// /// Unlocks this domain in real time. /// @@ -206,6 +329,16 @@ public void UnsetLock(string domainName) Client.unsetLock(domainName); } + /// + /// Unlocks this domain in real time. + /// + /// The domain name to unlock. + public async Task UnsetLockAsync(string domainName) + { + SetSignatureCookies("unsetLock", new object[] { domainName }); + await Client.unsetLockAsync(domainName); + } + /// /// Sets the DnEntries for this Domain, will replace all existing dns entries with the new entries. /// @@ -217,6 +350,17 @@ public void SetDnsEntries(string domainName, DnsEntry[] dnsEntries) Client.setDnsEntries(domainName, Mapper.Map(dnsEntries)); } + /// + /// Sets the DnEntries for this Domain, will replace all existing dns entries with the new entries. + /// + /// The domain mame to change the dns entries for. + /// The list of new DnsEntries for this domain. + public async Task SetDnsEntriesAsync(string domainName, DnsEntry[] dnsEntries) + { + SetSignatureCookies("setDnsEntries", new object[] { domainName, dnsEntries }); + await Client.setDnsEntriesAsync(domainName, Mapper.Map(dnsEntries)); + } + /// /// Starts an owner change of a Domain, brings additional costs with the following TLDs: /// .nl @@ -231,6 +375,20 @@ public void SetOwner(string domainName, WhoisContact registrantWhoisContact) Client.setOwner(domainName, Mapper.Map(registrantWhoisContact)); } + /// + /// Starts an owner change of a Domain, brings additional costs with the following TLDs: + /// .nl + /// .be + /// .eu + /// + /// The domainName to change the owner for. + /// The new contact data for this. + public async Task SetOwnerAsync(string domainName, WhoisContact registrantWhoisContact) + { + SetSignatureCookies("setOwner", new object[] { domainName, registrantWhoisContact }); + await Client.setOwnerAsync(domainName, Mapper.Map(registrantWhoisContact)); + } + /// /// Starts a contact change of a domain, this will replace all existing contacts. /// @@ -242,6 +400,17 @@ public void SetContacts(string domainName, WhoisContact[] contacts) Client.setContacts(domainName, Mapper.Map(contacts)); } + /// + /// Starts a contact change of a domain, this will replace all existing contacts. + /// + /// The domainName to change the contacts for. + /// The list of new contacts for this domain. + public async Task SetContactsAsync(string domainName, WhoisContact[] contacts) + { + SetSignatureCookies("setContacts", new object[] { domainName, contacts }); + await Client.setContactsAsync(domainName, Mapper.Map(contacts)); + } + /// /// Get TransIP supported TLDs. /// @@ -252,6 +421,16 @@ public Tld[] GetAllTldInfos() return Mapper.Map(Client.getAllTldInfos()); } + /// + /// Get TransIP supported TLDs. + /// + /// Array of Tld objects. + public async Task GetAllTldInfosAsync() + { + SetSignatureCookies("getAllTldInfos", new object[0]); + return Mapper.Map(await Client.getAllTldInfosAsync()); + } + /// /// Get info about a specific TLD. /// @@ -263,6 +442,17 @@ public Tld GetTldInfo(string tldName) return Mapper.Map(Client.getTldInfo(tldName)); } + /// + /// Get info about a specific TLD. + /// + /// The tld to get information about. + /// Tld object with info about this Tld. + public async Task GetTldInfoAsync(string tldName) + { + SetSignatureCookies("getTldInfo", new object[] { tldName }); + return Mapper.Map(await Client.getTldInfoAsync(tldName)); + } + /// /// Gets info about the action this domain is currently running. /// @@ -274,6 +464,17 @@ public DomainAction GetCurrentDomainAction(string domainName) return Mapper.Map(Client.getCurrentDomainAction(domainName)); } + /// + /// Gets info about the action this domain is currently running. + /// + /// Name of the domain. + /// If this domain is currently running an action, a corresponding DomainAction with info about the action will be returned. + public async Task GetCurrentDomainActionAsync(string domainName) + { + SetSignatureCookies("getCurrentDomainAction", new object[] { domainName }); + return Mapper.Map(await Client.getCurrentDomainActionAsync(domainName)); + } + /// /// Retries a failed domain action with new domain data. The Domain#name field must contain /// the name of the Domain, the nameserver, contacts, dnsEntries fields contain the new data for this domain. @@ -286,6 +487,18 @@ public void RetryCurrentDomainActionWithNewData(Domain domain) Client.retryCurrentDomainActionWithNewData(Mapper.Map(domain)); } + /// + /// Retries a failed domain action with new domain data. The Domain#name field must contain + /// the name of the Domain, the nameserver, contacts, dnsEntries fields contain the new data for this domain. + /// Set a field to null to not change the data. + /// + /// The domain with data to retry. + public async Task RetryCurrentDomainActionWithNewDataAsync(Domain domain) + { + SetSignatureCookies("retryCurrentDomainActionWithNewData", new object[] { domain }); + await Client.retryCurrentDomainActionWithNewDataAsync(Mapper.Map(domain)); + } + /// /// Retry a transfer action with a new authcode. /// @@ -297,6 +510,17 @@ public void RetryTransferWithDifferentAuthCode(Domain domain, string newAuthCode Client.retryTransferWithDifferentAuthCode(Mapper.Map(domain), newAuthCode); } + /// + /// Retry a transfer action with a new authcode. + /// + /// The domain to try the transfer with a different authcode for. + /// New authorization code to try. + public async Task RetryTransferWithDifferentAuthCodeAsync(Domain domain, string newAuthCode) + { + SetSignatureCookies("retryTransferWithDifferentAuthCode", new object[] { domain, newAuthCode }); + await Client.retryTransferWithDifferentAuthCodeAsync(Mapper.Map(domain), newAuthCode); + } + /// /// Cancels a failed domain action. /// @@ -306,6 +530,16 @@ public void CancelDomainAction(Domain domain) SetSignatureCookies("cancelDomainAction", new object[] {domain}); Client.cancelDomainAction(Mapper.Map(domain)); } + + /// + /// Cancels a failed domain action. + /// + /// The domain to cancel the action for. + public async Task CancelDomainActionAsync(Domain domain) + { + SetSignatureCookies("cancelDomainAction", new object[] { domain }); + await Client.cancelDomainActionAsync(Mapper.Map(domain)); + } } /// diff --git a/src/TransIp.Api/Dto/DnsEntry.cs b/src/TransIp.Api/Dto/DnsEntry.cs index b28de3c..687ec48 100644 --- a/src/TransIp.Api/Dto/DnsEntry.cs +++ b/src/TransIp.Api/Dto/DnsEntry.cs @@ -31,6 +31,8 @@ public class DnsEntry /// [DataMember(Name = "content")] public string Content { get; set; } + + public override string ToString() => $"{Name} IN {Expire} {Type} {Content}"; } /// @@ -44,6 +46,9 @@ public enum DnsEntryType MX, NS, TXT, - SRV + SRV, + SSHFP, + TLSA, + CAA } } \ No newline at end of file diff --git a/src/TransIp.Api/EncryptionHelper.cs b/src/TransIp.Api/EncryptionHelper.cs index abd19c2..7bf07f4 100644 --- a/src/TransIp.Api/EncryptionHelper.cs +++ b/src/TransIp.Api/EncryptionHelper.cs @@ -6,13 +6,12 @@ using System.Reflection; using System.Runtime.Serialization; using System.Security.Cryptography; -using System.Text; using System.Text.RegularExpressions; +using Microsoft.Security.Application; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.OpenSsl; using Org.BouncyCastle.Security; -using Encoder = Microsoft.Security.Application.Encoder; namespace TransIp.Api { @@ -36,71 +35,31 @@ public static class EncryptionHelper public static string Sign(string privateKey, object[] args) { var matches = PrivateKeyRegex.Matches(privateKey); - if (matches.Count == 0) - { + if (matches.Count == 0) { throw new Exception("Invalid private key."); } - /*var key = matches[0].Groups[2].Value; - key = WhitespaceRegex.Replace(key, ""); - key = ChunkSplit(key, 64, "\n"); - key = "-----BEGIN RSA PRIVATE KEY-----\n" + key + "-----END RSA PRIVATE KEY-----";*/ - var digest = Sha512Asn1(EncodeArguments(args)); var signature = Encrypt(digest, privateKey); return Convert.ToBase64String(signature); } - private static string ChunkSplit(string input, int chunkLength, string end) - { - var sb = new StringBuilder(); - - int position = 0; - while (position < input.Length) - { - for (var i = 0; i < chunkLength && position < input.Length; ++i) - { - sb.Append(input[position++]); - } - - if (position < input.Length) - { - sb.Append(end); - } - } - - sb.Append(end); - return sb.ToString(); - } - private static byte[] Sha512Asn1(string data) { var signature = new[] { - 0x30, - 0x51, - 0x30, - 0x0d, - 0x06, - 0x09, - 0x60, - 0x86, - 0x48, - 0x01, - 0x65, - 0x03, - 0x04, - 0x02, - 0x03, - 0x05, - 0x00, - 0x04, + 0x30, 0x51, 0x30, + 0x0d, 0x06, 0x09, + 0x60, 0x86, 0x48, + 0x01, 0x65, 0x03, + 0x04, 0x02, 0x03, + 0x05, 0x00, 0x04, 0x40 }; var hashAlg = SHA512.Create(); - var hash = hashAlg.ComputeHash(Encoding.ASCII.GetBytes(data)); + var hash = hashAlg.ComputeHash(System.Text.Encoding.ASCII.GetBytes(data)); return signature.Select(x => (byte) x).Concat(hash).ToArray(); } @@ -112,18 +71,16 @@ private static byte[] Encrypt(byte[] digest, string key) var pemObject = pemReader.ReadObject(); ICipherParameters cipherParameters; - if (pemObject is RsaPrivateCrtKeyParameters) - { - cipherParameters = (RsaPrivateCrtKeyParameters)pemObject; - } - else if (pemObject is AsymmetricCipherKeyPair) - { - var keyPair = (AsymmetricCipherKeyPair) pemObject; - cipherParameters = keyPair.Private; - } - else - { - throw new Exception("Unsupported private key format. Got object of type '" + pemObject.GetType() + "' from PEM reader."); + switch (pemObject) { + case RsaPrivateCrtKeyParameters parameters: + cipherParameters = parameters; + break; + case AsymmetricCipherKeyPair _: + var keyPair = (AsymmetricCipherKeyPair) pemObject; + cipherParameters = keyPair.Private; + break; + default: + throw new Exception("Unsupported private key format. Got object of type '" + pemObject.GetType() + "' from PEM reader."); } var cipher = CipherUtilities.GetCipher("RSA/None/PKCS1Padding"); @@ -134,27 +91,22 @@ private static byte[] Encrypt(byte[] digest, string key) private static string EncodeArguments(object args, string keyPrefix = null) { - if (!CanEnumerate(args)) - { + if (!CanEnumerate(args)) { return Encode(args); } var encodedData = new List(); - foreach (var arg in Enumerate(args)) - { + foreach (var arg in Enumerate(args)) { var encodedKey = keyPrefix == null ? Encoder.UrlEncode(arg.Key) : keyPrefix + "[" + Encoder.UrlEncode(arg.Key) + "]"; - if (CanEnumerate(arg.Value)) - { + if (CanEnumerate(arg.Value)) { encodedData.Add(EncodeArguments(arg.Value, encodedKey)); - } - else - { + } else { encodedData.Add(encodedKey + "=" + Encode(arg.Value)); } } - return String.Join("&", encodedData); + return string.Join("&", encodedData); } /// @@ -166,57 +118,41 @@ public static string Encode(object obj) { var result = obj != null ? Encoder.UrlEncode(obj.ToString()) : ""; result = result.Replace("%7E", "~"); // Not sure if this is necessary. - result = EscapeRegex.Replace(result, match => { return match.Value.ToUpper(); }); + result = EscapeRegex.Replace(result, match => match.Value.ToUpper()); return result; } private static bool CanEnumerate(object arg) { - if (arg == null) - { - return false; - } - if (arg is IEnumerable && !(arg is string)) - { - return true; - } - if (arg.GetType().GetCustomAttributes(typeof (DataContractAttribute), false).Any()) - { - return true; + switch (arg) { + case null: + return false; + case IEnumerable _ when !(arg is string): + return true; } - return false; + return arg.GetType().GetCustomAttributes(typeof (DataContractAttribute), false).Any(); } private static IDictionary Enumerate(object arg) { var result = new Dictionary(); - if (arg is IEnumerable && !(arg is string)) - { - int counter = 0; - foreach (var obj in (IEnumerable) arg) - { - if (obj is KeyValuePair) - { - var keyValuePair = (KeyValuePair) obj; + if (arg is IEnumerable enumerable && !(enumerable is string)) { + var counter = 0; + foreach (var obj in enumerable) { + if (obj is KeyValuePair keyValuePair) { result.Add(keyValuePair.Key, keyValuePair.Value); - } - else - { + } else { result.Add(counter.ToString(), obj); } counter++; } - } - else if (arg.GetType().GetCustomAttributes(typeof (DataContractAttribute), false).Any()) - { - foreach (var member in arg.GetType().GetMembers(BindingFlags.Public | BindingFlags.Instance)) - { + } else if (arg.GetType().GetCustomAttributes(typeof (DataContractAttribute), false).Any()) { + foreach (var member in arg.GetType().GetMembers(BindingFlags.Public | BindingFlags.Instance)) { var attr = member.GetCustomAttribute(); - if (attr != null) - { + if (attr != null) { result.Add(attr.Name ?? member.Name, member is FieldInfo ? ((FieldInfo) member).GetValue(arg) : ((PropertyInfo) member).GetValue(arg)); } diff --git a/src/TransIp.Api/Properties/AssemblyInfo.cs b/src/TransIp.Api/Properties/AssemblyInfo.cs deleted file mode 100644 index 288e76d..0000000 --- a/src/TransIp.Api/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,6 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -[assembly: AssemblyTitle("TransIp.Api")] -[assembly: ComVisible(false)] -[assembly: Guid("6c0477dc-c33e-45e5-be4c-d0f267e7925a")] \ No newline at end of file diff --git a/src/TransIp.Api/TransIp.Api.csproj b/src/TransIp.Api/TransIp.Api.csproj index 3596775..ce2d36e 100644 --- a/src/TransIp.Api/TransIp.Api.csproj +++ b/src/TransIp.Api/TransIp.Api.csproj @@ -1,145 +1,27 @@ - - - + - Debug - AnyCPU - {0C230541-FF71-4DDC-9AAC-213990AC4AFA} - Library - Properties - TransIp.Api - TransIp.Api - v4.5 - 512 - ..\ - true + netcoreapp2.0 + true + false + TransIP.NET + Wouter Janson, jwvdiermen + + TransIP.NET + A .Net Core client library for the TransIP Api, based on the work of jwvdiermen. + WouterJanson + https://github.com/WouterJanson/TransIP.NET/blob/master/LICENSE + https://github.com/WouterJanson/TransIP.NET + TransIP.NET + 1.1.2 + 1.1.2.0 + 1.1.2.0 + TransIP, API, DNS, Domain - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - bin\Debug\TransIp.Api.XML - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - bin\Release\TransIp.Api.XML - - - - - - - ..\packages\AntiXSS.4.2.1\lib\net40\AntiXssLibrary.dll - - - False - ..\packages\AutoMapper.3.1.1\lib\net40\AutoMapper.dll - - - ..\packages\AutoMapper.3.1.1\lib\net40\AutoMapper.Net4.dll - - - ..\packages\BouncyCastle.1.7.0\lib\Net20\BouncyCastle.Crypto.dll - - - ..\packages\AntiXSS.4.2.1\lib\net40\HtmlSanitizationLibrary.dll - - - - - - - - - - Properties\SharedAssemblyInfo.cs - - - - - - - - - - - - - - - - - - True - True - Reference.svcmap - - - - - - - Reference.svcmap - - - Reference.svcmap - - - Reference.svcmap - - - Reference.svcmap - - - - - - - - - - - - - - - - - - WCF Proxy Generator - Reference.cs - - - - AutoMapper.Net4.dll - PreserveNewest - + + + + + - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - \ No newline at end of file diff --git a/src/TransIp.Api/TransIp.Api.nuspec b/src/TransIp.Api/TransIp.Api.nuspec deleted file mode 100644 index fb9b3d4..0000000 --- a/src/TransIp.Api/TransIp.Api.nuspec +++ /dev/null @@ -1,16 +0,0 @@ - - - - $id$ - $version$ - $title$ - $author$ - $author$ - https://raw.github.com/jwvdiermen/TransIP-API/master/LICENSE - https://github.com/jwvdiermen/TransIP-API - false - Client library for the TransIP API written in C#. - Copyright (c) 2011-2014 Crealuz - All rights reserved - API Service TransIP - - \ No newline at end of file diff --git a/src/TransIp.Api/packages.config b/src/TransIp.Api/packages.config deleted file mode 100644 index e4d009a..0000000 --- a/src/TransIp.Api/packages.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/shared/ApiSettings.cs b/src/shared/ApiSettings.cs deleted file mode 100644 index 14359a0..0000000 --- a/src/shared/ApiSettings.cs +++ /dev/null @@ -1,25 +0,0 @@ - -namespace TransIp.Api.Examples.Shared -{ - /// - /// Contains the API settings used with the examples. - /// Replaces these values with your details! - /// - public static class ApiSettings - { - /// - /// The client mode. - /// - public static ClientMode Mode = ClientMode.ReadOnly; - - /// - /// The login. - /// - public static readonly string Login = "YOUR_USERNAME"; - - /// - /// The private key. - /// - public static readonly string PrivateKey = @"YOUR_PRIVATE_KEY"; - } -} \ No newline at end of file diff --git a/src/shared/SharedAssemblyInfo.cs b/src/shared/SharedAssemblyInfo.cs deleted file mode 100644 index 5e6b879..0000000 --- a/src/shared/SharedAssemblyInfo.cs +++ /dev/null @@ -1,7 +0,0 @@ -using System.Reflection; - -[assembly: AssemblyProduct("TransIP API")] -[assembly: AssemblyCompany("Crealuz")] -[assembly: AssemblyCopyright("Copyright © 2011-2014 Crealuz - All rights reserved")] -[assembly: AssemblyVersion("0.1.6")] -[assembly: AssemblyFileVersion("0.1.6")] \ No newline at end of file