Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes #17

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions Api.Tests/Api.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="1.3.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Api\Api.csproj" />
</ItemGroup>

</Project>
28 changes: 28 additions & 0 deletions Api.Tests/ApiTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System;
using Xunit;
using KoenZomers.UniFi.Api.Tests.Fakes;
using System.Threading.Tasks;

namespace KoenZomers.UniFi.Api.Tests
{
public class ApiTests
{
[Fact]
public void Should_BuildApi_When_Requested()
{
IApi api = new Api(new Uri("https://test.com"));
}

[Fact]
public async Task Should_Authenticate_When_Requested()
{
IApi api = new Api(
new Uri("https://test.com"),
"test",
new FakeHttpUtility());

Assert.True(await api.Authenticate("test", "test"));
Assert.True(api.IsAuthenticated);
}
}
}
42 changes: 42 additions & 0 deletions Api.Tests/Fakes/FakeHttpUtility.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using Newtonsoft.Json;
using System;
using System.Net;
using System.Threading.Tasks;

namespace KoenZomers.UniFi.Api.Tests.Fakes
{
public class FakeHttpUtility : IHttpUtility
{
public string CurrentUnifiSite = "default";

public async Task<string> AuthenticateViaJsonPostMethod(Uri url, string username, string password, CookieContainer cookieContainer, int timeout = 60000)
{
return JsonConvert.SerializeObject(new { meta = new { rc = "ok" } });
}

public void DisableSslValidation()
{
throw new NotImplementedException();
}

public void EnableTls11and12()
{
throw new NotImplementedException();
}

public Task<string> GetRequestResult(Uri url, CookieContainer cookieContainer, int timeout = 60000)
{
throw new NotImplementedException();
}

public Task<string> LogoutViaJsonPostMethod(Uri url, CookieContainer cookieContainer, int timeout = 60000)
{
throw new NotImplementedException();
}

public Task<string> PostRequest(Uri url, string postData, CookieContainer cookieContainer, int timeout = 60000)
{
throw new NotImplementedException();
}
}
}
4 changes: 4 additions & 0 deletions Api.Tests/xunit.runner.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"$schema": "https://xunit.net/schema/current/xunit.runner.schema.json",
"methodDisplay": "method"
}
101 changes: 58 additions & 43 deletions Api/Api.cs

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions Api/HttpUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,20 @@ namespace KoenZomers.UniFi.Api
/// <summary>
/// Internal utility class for Http communication with the UniFi Controller
/// </summary>
internal static class HttpUtility
public class HttpUtility : IHttpUtility
{
/// <summary>
/// Disables SSL Validation in case of self signed SSL certificates being used
/// </summary>
public static void DisableSslValidation()
public void DisableSslValidation()
{
ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
}

/// <summary>
/// Enables connecting to a remote server hosting UniFi using a TLS 1.1 or TLS 1.2 certificate
/// </summary>
public static void EnableTls11and12()
public void EnableTls11and12()
{
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
}
Expand All @@ -35,7 +35,7 @@ public static void EnableTls11and12()
/// <param name="cookieContainer">Cookies which have been recorded for this session</param>
/// <param name="timeout">Timeout in milliseconds on how long the request may take. Default = 60000 = 60 seconds.</param>
/// <returns>Contents of the page</returns>
public async static Task<string> GetRequestResult(Uri url, CookieContainer cookieContainer, int timeout = 60000)
public async Task<string> GetRequestResult(Uri url, CookieContainer cookieContainer, int timeout = 60000)
{
// Construct the request
var request = (HttpWebRequest)WebRequest.Create(url);
Expand Down Expand Up @@ -70,7 +70,7 @@ public async static Task<string> GetRequestResult(Uri url, CookieContainer cooki
/// <param name="cookieContainer">Cookies which have been recorded for this session</param>
/// <param name="timeout">Timeout in milliseconds on how long the request may take. Default = 60000 = 60 seconds.</param>
/// <returns>The website contents returned by the webserver after posting the data</returns>
public async static Task<string> PostRequest(Uri url, string postData, CookieContainer cookieContainer, int timeout = 60000)
public async Task<string> PostRequest(Uri url, string postData, CookieContainer cookieContainer, int timeout = 60000)
{
// Construct the POST request
var request = (HttpWebRequest)WebRequest.Create(url);
Expand All @@ -83,7 +83,7 @@ public async static Task<string> PostRequest(Uri url, string postData, CookieCon

// Check if the have a Cross Site Request Forgery cookie and if so, add it as the X-Csrf-Token header which is required by UniFi when making a POST
var csrfCookie = cookieContainer.GetAllCookies().FirstOrDefault(c => c.Name == "csrf_token");
if(csrfCookie != null)
if (csrfCookie != null)
{
request.Headers.Add("X-Csrf-Token", csrfCookie.Value);
}
Expand Down Expand Up @@ -132,7 +132,7 @@ public async static Task<string> PostRequest(Uri url, string postData, CookieCon
/// <param name="cookieContainer">Cookies which have been recorded for this session</param>
/// <param name="timeout">Timeout in milliseconds on how long the request may take. Default = 60000 = 60 seconds.</param>
/// <returns>The website contents returned by the webserver after posting the data</returns>
public async static Task<string> AuthenticateViaJsonPostMethod(Uri url, string username, string password, CookieContainer cookieContainer, int timeout = 60000)
public async Task<string> AuthenticateViaJsonPostMethod(Uri url, string username, string password, CookieContainer cookieContainer, int timeout = 60000)
{
// Construct the POST request which performs the login
var request = (HttpWebRequest)WebRequest.Create(url);
Expand Down Expand Up @@ -215,7 +215,7 @@ public async static Task<string> AuthenticateViaJsonPostMethod(Uri url, string u
/// <param name="cookieContainer">Cookies which have been recorded for this session</param>
/// <param name="timeout">Timeout in milliseconds on how long the request may take. Default = 60000 = 60 seconds.</param>
/// <returns>The website contents returned by the webserver after posting the data</returns>
public async static Task<string> LogoutViaJsonPostMethod(Uri url, CookieContainer cookieContainer, int timeout = 60000)
public async Task<string> LogoutViaJsonPostMethod(Uri url, CookieContainer cookieContainer, int timeout = 60000)
{
// Construct the POST request which performs the login
var request = (HttpWebRequest)WebRequest.Create(url);
Expand Down
36 changes: 36 additions & 0 deletions Api/IApi.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using KoenZomers.UniFi.Api.Responses;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace KoenZomers.UniFi.Api
{
public interface IApi
{
Uri BaseUri { get; }
int ConnectionTimeout { get; set; }
bool IsAuthenticated { get; }
string SiteId { get; }

Task<bool> Authenticate(string username, string password);
Task<ResponseEnvelope<Clients>> AuthorizeGuest(string macAddress);
Task<ResponseEnvelope<Clients>> AuthorizeGuest(string macAddress, string unifiSiteId);
Task<ResponseEnvelope<Clients>> BlockClient(Clients client);
Task<ResponseEnvelope<Clients>> BlockClient(string macAddress);
void DisableSslValidation();
void EnableTls11and12();
Task<List<Clients>> GetActiveClients();
Task<List<Clients>> GetActiveClients(string unifiSiteId);
Task<List<Clients>> GetAllClients();
Task<List<ClientSession>> GetClientHistory(string macAddress, int limit = 5);
Task<List<Device>> GetDevices();
Task<List<Site>> GetSites();
Task<bool> Logout();
Task<ResponseEnvelope<Clients>> RenameClient(Clients client, string name);
Task<ResponseEnvelope<Clients>> RenameClient(string userId, string name);
Task<ResponseEnvelope<Clients>> UnauthorizeGuest(string macAddress);
Task<ResponseEnvelope<Clients>> UnauthorizeGuest(string macAddress, string unifiSiteId);
Task<ResponseEnvelope<Clients>> UnblockClient(Clients client);
Task<ResponseEnvelope<Clients>> UnblockClient(string macAddress);
}
}
16 changes: 16 additions & 0 deletions Api/IHttpUtility.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using System.Net;
using System.Threading.Tasks;

namespace KoenZomers.UniFi.Api
{
public interface IHttpUtility
{
Task<string> AuthenticateViaJsonPostMethod(Uri url, string username, string password, CookieContainer cookieContainer, int timeout = 60000);
void DisableSslValidation();
void EnableTls11and12();
Task<string> GetRequestResult(Uri url, CookieContainer cookieContainer, int timeout = 60000);
Task<string> LogoutViaJsonPostMethod(Uri url, CookieContainer cookieContainer, int timeout = 60000);
Task<string> PostRequest(Uri url, string postData, CookieContainer cookieContainer, int timeout = 60000);
}
}
4 changes: 2 additions & 2 deletions Api/KoenZomers.UniFi.Api.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 12 additions & 3 deletions KoenZomers.Tools.UniFi.Api.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26228.4
# Visual Studio Version 16
VisualStudioVersion = 16.0.30804.86
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleApp", "ConsoleApp\ConsoleApp.csproj", "{0423F938-84B6-44F2-BE25-B47F9EDB1FA8}"
EndProject
Expand All @@ -15,7 +15,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Api", "Api\Api.csproj", "{9
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsFormsApp", "WindowsFormsApp\WindowsFormsApp.csproj", "{FB08758B-91E8-4E60-A93D-6E135C336E5B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTestProject", "UnitTestProject\UnitTestProject.csproj", "{7A3DE600-B66D-4293-86B0-961B2899DE51}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTestProject", "UnitTestProject\UnitTestProject.csproj", "{7A3DE600-B66D-4293-86B0-961B2899DE51}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Api.Tests", "Api.Tests\Api.Tests.csproj", "{C242E7EE-800A-48F6-B00A-4D5AEA7BE0E8}"
ProjectSection(ProjectDependencies) = postProject
{9F24A03F-08F5-42D5-8CD9-E4888F780E18} = {9F24A03F-08F5-42D5-8CD9-E4888F780E18}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -39,6 +44,10 @@ Global
{7A3DE600-B66D-4293-86B0-961B2899DE51}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7A3DE600-B66D-4293-86B0-961B2899DE51}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7A3DE600-B66D-4293-86B0-961B2899DE51}.Release|Any CPU.Build.0 = Release|Any CPU
{C242E7EE-800A-48F6-B00A-4D5AEA7BE0E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C242E7EE-800A-48F6-B00A-4D5AEA7BE0E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C242E7EE-800A-48F6-B00A-4D5AEA7BE0E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C242E7EE-800A-48F6-B00A-4D5AEA7BE0E8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down