Skip to content
This repository has been archived by the owner on Apr 8, 2024. It is now read-only.

Commit

Permalink
Merge pull request #323 from aspriddell/add-geolocation-api
Browse files Browse the repository at this point in the history
Add geolocation api
  • Loading branch information
aspriddell authored Aug 1, 2022
2 parents 43a8820 + 6473472 commit 4ec639d
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 11 deletions.
23 changes: 21 additions & 2 deletions DragonFruit.Six.Api.Tests/Utils/ServiceTests.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// Dragon6 API Copyright DragonFruit Network <inbox@dragonfruit.network>
// Licensed under Apache-2. Refer to the LICENSE file for more info

using System.Linq;
using System.Threading.Tasks;
using DragonFruit.Six.Api.Accounts;
using DragonFruit.Six.Api.Services.Geolocation;
using DragonFruit.Six.Api.Services.Status;
using NUnit.Framework;

Expand All @@ -12,7 +13,25 @@ namespace DragonFruit.Six.Api.Tests.Utils
public class ServiceTests : Dragon6ApiTest
{
[Test]
public async Task TestGeolocation() => await Client.GeolocateAsync();
public async Task TestGeolocation()
{
// test the request works without throwing
// as we don't know who's running this, there's no real way to validate correctness of this part
await Client.GeolocateAsync().ConfigureAwait(false);

var addressInfo = await Client.GeolocateAsync("8.8.8.8", "172.217.16.238", "194.39.167.145", "2620:119:35::35").ConfigureAwait(false);
var addressDirectory = addressInfo.ToDictionary(x => x.IP);

// google services
Assert.AreEqual("Google", addressDirectory["8.8.8.8"].ServiceProvider);
Assert.AreEqual("Google Servers", addressDirectory["172.217.16.238"].ServiceProvider);

// IPv6 DNS server
Assert.AreEqual("Cisco OpenDNS, LLC", addressDirectory["2620:119:35::35"].ServiceProvider);

// random ip address from UK
Assert.AreEqual("United Kingdom", addressDirectory["194.39.167.145"].CountryName);
}

[Test]
public async Task TestServerStatus() => await Client.GetServerStatusAsync();
Expand Down
6 changes: 0 additions & 6 deletions DragonFruit.Six.Api/Accounts/UbisoftAccountExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DragonFruit.Data;
using DragonFruit.Six.Api.Accounts.Entities;
using DragonFruit.Six.Api.Accounts.Enums;
using DragonFruit.Six.Api.Accounts.Requests;
Expand Down Expand Up @@ -66,10 +65,5 @@ public static Task<IReadOnlyDictionary<string, UbisoftAccountActivity>> GetAccou
var request = new UbisoftAccountActivityRequest(accounts);
return client.PerformAsync<JObject>(request).ContinueWith(t => t.Result.DeserializeUbisoftAccountActivity());
}

/// <summary>
/// Get the current device location based on a IP Geolocation lookup
/// </summary>
public static Task<Geolocation> GeolocateAsync(this ApiClient client) => client.PerformAsync<Geolocation>(new UbisoftGeolocationRequest());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
using System;
using Newtonsoft.Json;

namespace DragonFruit.Six.Api.Accounts.Entities
namespace DragonFruit.Six.Api.Services.Geolocation
{
[Serializable]
public class Geolocation
Expand Down
51 changes: 51 additions & 0 deletions DragonFruit.Six.Api/Services/Geolocation/GeolocationExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Dragon6 API Copyright DragonFruit Network <inbox@dragonfruit.network>
// Licensed under Apache-2. Refer to the LICENSE file for more info

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using DragonFruit.Data;
using DragonFruit.Data.Serializers.Newtonsoft;
using DragonFruit.Six.Api.Services.Geolocation.Requests;
using Newtonsoft.Json.Linq;

namespace DragonFruit.Six.Api.Services.Geolocation
{
public static class GeolocationExtensions
{
/// <summary>
/// Get the current device location based on a IP Geolocation lookup
/// </summary>
public static Task<Geolocation> GeolocateAsync<T>(this T client) where T : ApiClient<ApiJsonSerializer>
{
return client.PerformAsync<Geolocation>(new UbisoftSelfGeolocationRequest());
}

/// <summary>
/// Get the approximate location and ISP info for a collection of IP addresses
/// </summary>
/// <param name="client">The <see cref="Dragon6Client"/> to use</param>
/// <param name="ips">A collection of IP addresses to lookup</param>
/// <returns>An <see cref="IReadOnlyCollection{T}"/> containing the IP addresses and their approximate location</returns>
public static async Task<IReadOnlyCollection<Geolocation>> GeolocateAsync(this Dragon6Client client, params string[] ips)
{
var request = new UbisoftGeolocationRequest(ips);
var container = await client.PerformAsync<JObject>(request).ConfigureAwait(false);

return container["ipLocations"]?.ToObject<Geolocation[]>() ?? Array.Empty<Geolocation>();
}

/// <summary>
/// Get the approximate location and ISP info for a collection of IP addresses
/// </summary>
/// <param name="client">The <see cref="Dragon6Client"/> to use</param>
/// <param name="ips">A collection of IP addresses to lookup</param>
/// <returns>An <see cref="IReadOnlyCollection{T}"/> containing the IP addresses and their approximate location</returns>
public static Task<IReadOnlyCollection<Geolocation>> GeolocateAsync(this Dragon6Client client, params IPAddress[] ips)
{
return GeolocateAsync(client, ips.Select(x => x.ToString()).ToArray());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Dragon6 API Copyright DragonFruit Network <inbox@dragonfruit.network>
// Licensed under Apache-2. Refer to the LICENSE file for more info

using System.Collections.Generic;
using DragonFruit.Data;
using DragonFruit.Data.Parameters;

namespace DragonFruit.Six.Api.Services.Geolocation.Requests
{
/// <summary>
/// Creates a request to get the approximate location a collection of provided IP addresses
/// </summary>
public class UbisoftGeolocationRequest : UbiApiRequest
{
public override string Path => $"{Endpoints.BaseEndpoint}/v2/iplocation";

public UbisoftGeolocationRequest(IEnumerable<string> addresses)
{
Addresses = addresses;
}

[QueryParameter("ips", CollectionConversionMode.Concatenated)]
public IEnumerable<string> Addresses { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,15 @@
using DragonFruit.Data.Requests;
using DragonFruit.Six.Api.Enums;

namespace DragonFruit.Six.Api.Accounts.Requests
namespace DragonFruit.Six.Api.Services.Geolocation.Requests
{
public class UbisoftGeolocationRequest : ApiRequest, IRequestExecutingCallback
/// <summary>
/// Creates a request to get the approximate location of the current user-agent
/// </summary>
/// <remarks>
/// While this endpoint does not require authentication, a valid Ubi-AppId header will be attached
/// </remarks>
public class UbisoftSelfGeolocationRequest : ApiRequest, IRequestExecutingCallback
{
public override string Path => $"{Endpoints.BaseEndpoint}/v2/profiles/me/iplocation";

Expand Down

0 comments on commit 4ec639d

Please sign in to comment.