Skip to content

Commit

Permalink
Use unified BattleNet server (#813)
Browse files Browse the repository at this point in the history
Use unified BattleNet server

Resolves #812.
  • Loading branch information
martincostello authored Nov 14, 2023
1 parent 515ada5 commit 8dfccb3
Show file tree
Hide file tree
Showing 7 changed files with 304 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,30 @@ public static class BattleNetAuthenticationDefaults
/// </summary>
public static readonly string CallbackPath = "/signin-battlenet";

/// <summary>
/// A class containing the URLs for the unified global BattleNet OAuth servers.
/// </summary>
public static class Unified
{
/// <summary>
/// Default value for <see cref="OAuthOptions.AuthorizationEndpoint"/>.
/// </summary>
public static readonly string AuthorizationEndpoint = "https://oauth.battle.net/oauth/authorize";

/// <summary>
/// Default value for <see cref="OAuthOptions.TokenEndpoint"/>.
/// </summary>
public static readonly string TokenEndpoint = "https://oauth.battle.net/oauth/token";

/// <summary>
/// Default value for <see cref="OAuthOptions.UserInformationEndpoint"/>.
/// </summary>
public static readonly string UserInformationEndpoint = "https://oauth.battle.net/oauth/userinfo";
}

/// <summary>
/// A class containing the URLs for the BattleNet OAuth servers for America.
/// </summary>
public static class America
{
/// <summary>
Expand All @@ -49,74 +73,86 @@ public static class America
public static readonly string UserInformationEndpoint = "https://us.battle.net/oauth/userinfo";
}

/// <summary>
/// A class containing the URLs for the BattleNet OAuth servers for Europe.
/// </summary>
public static class Europe
{
/// <summary>
/// Default value for <see cref="OAuthOptions.AuthorizationEndpoint"/> for EU servers.
/// Default value for <see cref="OAuthOptions.AuthorizationEndpoint"/> for European servers.
/// </summary>
public static readonly string AuthorizationEndpoint = "https://eu.battle.net/oauth/authorize";

/// <summary>
/// Default value for <see cref="OAuthOptions.TokenEndpoint"/> for EU servers.
/// Default value for <see cref="OAuthOptions.TokenEndpoint"/> for European servers.
/// </summary>
public static readonly string TokenEndpoint = "https://eu.battle.net/oauth/token";

/// <summary>
/// Default value for <see cref="OAuthOptions.UserInformationEndpoint"/> for EU servers.
/// Default value for <see cref="OAuthOptions.UserInformationEndpoint"/> for European servers.
/// </summary>
public static readonly string UserInformationEndpoint = "https://eu.battle.net/oauth/userinfo";
}

/// <summary>
/// A class containing the URLs for the BattleNet OAuth servers for Korea.
/// </summary>
public static class Korea
{
/// <summary>
/// Default value for <see cref="OAuthOptions.AuthorizationEndpoint"/> for KR servers.
/// Default value for <see cref="OAuthOptions.AuthorizationEndpoint"/> for Korean servers.
/// </summary>
public static readonly string AuthorizationEndpoint = "https://kr.battle.net/oauth/authorize";

/// <summary>
/// Default value for <see cref="OAuthOptions.TokenEndpoint"/> for KR servers.
/// Default value for <see cref="OAuthOptions.TokenEndpoint"/> for Korean servers.
/// </summary>
public static readonly string TokenEndpoint = "https://kr.battle.net/oauth/token";

/// <summary>
/// Default value for <see cref="OAuthOptions.UserInformationEndpoint"/> for KR servers.
/// Default value for <see cref="OAuthOptions.UserInformationEndpoint"/> for Korean servers.
/// </summary>
public static readonly string UserInformationEndpoint = "https://kr.battle.net/oauth/userinfo";
}

/// <summary>
/// A class containing the URLs for the BattleNet OAuth servers for Taiwan.
/// </summary>
public static class Taiwan
{
/// <summary>
/// Default value for <see cref="OAuthOptions.AuthorizationEndpoint"/> for TW servers.
/// Default value for <see cref="OAuthOptions.AuthorizationEndpoint"/> for Taiwanese servers.
/// </summary>
public static readonly string AuthorizationEndpoint = "https://tw.battle.net/oauth/authorize";

/// <summary>
/// Default value for <see cref="OAuthOptions.TokenEndpoint"/> for TW servers.
/// Default value for <see cref="OAuthOptions.TokenEndpoint"/> for Taiwanese servers.
/// </summary>
public static readonly string TokenEndpoint = "https://tw.battle.net/oauth/token";

/// <summary>
/// Default value for <see cref="OAuthOptions.UserInformationEndpoint"/> for TW servers.
/// Default value for <see cref="OAuthOptions.UserInformationEndpoint"/> for Taiwanese servers.
/// </summary>
public static readonly string UserInformationEndpoint = "https://tw.battle.net/oauth/userinfo";
}

/// <summary>
/// A class containing the URLs for the BattleNet OAuth servers for China.
/// </summary>
public static class China
{
/// <summary>
/// Default value for <see cref="OAuthOptions.AuthorizationEndpoint"/> for CN servers.
/// Default value for <see cref="OAuthOptions.AuthorizationEndpoint"/> for China servers.
/// </summary>
public static readonly string AuthorizationEndpoint = "https://www.battlenet.com.cn/oauth/authorize";

/// <summary>
/// Default value for <see cref="OAuthOptions.TokenEndpoint"/> for CN servers.
/// Default value for <see cref="OAuthOptions.TokenEndpoint"/> for China servers.
/// </summary>
public static readonly string TokenEndpoint = "https://www.battlenet.com.cn/oauth/token";

/// <summary>
/// Default value for <see cref="OAuthOptions.UserInformationEndpoint"/> for CN servers.
/// Default value for <see cref="OAuthOptions.UserInformationEndpoint"/> for China servers.
/// </summary>
public static readonly string UserInformationEndpoint = "https://www.battlenet.com.cn/oauth/userinfo";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
*/

using AspNet.Security.OAuth.BattleNet;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;

namespace Microsoft.Extensions.DependencyInjection;

Expand Down Expand Up @@ -69,6 +71,7 @@ public static AuthenticationBuilder AddBattleNet(
[CanBeNull] string caption,
[NotNull] Action<BattleNetAuthenticationOptions> configuration)
{
builder.Services.TryAddSingleton<IPostConfigureOptions<BattleNetAuthenticationOptions>, BattleNetPostConfigureOptions>();
return builder.AddOAuth<BattleNetAuthenticationOptions, BattleNetAuthenticationHandler>(scheme, caption, configuration);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,58 +16,17 @@ public class BattleNetAuthenticationOptions : OAuthOptions
public BattleNetAuthenticationOptions()
{
ClaimsIssuer = BattleNetAuthenticationDefaults.Issuer;

CallbackPath = BattleNetAuthenticationDefaults.CallbackPath;

Region = BattleNetAuthenticationRegion.America;
Region = BattleNetAuthenticationRegion.Unified;

ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "id");
ClaimActions.MapJsonKey(ClaimTypes.Name, "battletag");
}

/// <summary>
/// Sets the region used to determine the appropriate API endpoints when communicating
/// with BattleNet (by default, <see cref="BattleNetAuthenticationRegion.America"/>).
/// with BattleNet. The default value is <see cref="BattleNetAuthenticationRegion.Unified"/>.
/// </summary>
public BattleNetAuthenticationRegion Region
{
set
{
switch (value)
{
case BattleNetAuthenticationRegion.America:
AuthorizationEndpoint = BattleNetAuthenticationDefaults.America.AuthorizationEndpoint;
TokenEndpoint = BattleNetAuthenticationDefaults.America.TokenEndpoint;
UserInformationEndpoint = BattleNetAuthenticationDefaults.America.UserInformationEndpoint;
break;

case BattleNetAuthenticationRegion.China:
AuthorizationEndpoint = BattleNetAuthenticationDefaults.China.AuthorizationEndpoint;
TokenEndpoint = BattleNetAuthenticationDefaults.China.TokenEndpoint;
UserInformationEndpoint = BattleNetAuthenticationDefaults.China.UserInformationEndpoint;
break;

case BattleNetAuthenticationRegion.Europe:
AuthorizationEndpoint = BattleNetAuthenticationDefaults.Europe.AuthorizationEndpoint;
TokenEndpoint = BattleNetAuthenticationDefaults.Europe.TokenEndpoint;
UserInformationEndpoint = BattleNetAuthenticationDefaults.Europe.UserInformationEndpoint;
break;

case BattleNetAuthenticationRegion.Korea:
AuthorizationEndpoint = BattleNetAuthenticationDefaults.Korea.AuthorizationEndpoint;
TokenEndpoint = BattleNetAuthenticationDefaults.Korea.TokenEndpoint;
UserInformationEndpoint = BattleNetAuthenticationDefaults.Korea.UserInformationEndpoint;
break;

case BattleNetAuthenticationRegion.Taiwan:
AuthorizationEndpoint = BattleNetAuthenticationDefaults.Taiwan.AuthorizationEndpoint;
TokenEndpoint = BattleNetAuthenticationDefaults.Taiwan.TokenEndpoint;
UserInformationEndpoint = BattleNetAuthenticationDefaults.Taiwan.UserInformationEndpoint;
break;

default:
throw new ArgumentOutOfRangeException($"Region '{value}' is unsupported.", value, nameof(value));
}
}
}
public BattleNetAuthenticationRegion Region { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,38 @@ namespace AspNet.Security.OAuth.BattleNet;
/// </summary>
public enum BattleNetAuthenticationRegion
{
/// <summary>
/// The region for the Americas.
/// </summary>
America = 0,

/// <summary>
/// The region for China.
/// </summary>
China = 1,

/// <summary>
/// The region for Europe.
/// </summary>
Europe = 2,

/// <summary>
/// The region for Korea.
/// </summary>
Korea = 3,
Taiwan = 4

/// <summary>
/// The region for Taiwan.
/// </summary>
Taiwan = 4,

/// <summary>
/// The unified global region.
/// </summary>
Unified = 5,

/// <summary>
/// A custom region. Use this value to use custom endpoints.
/// </summary>
Custom = 6,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers
* for more information concerning the license and the contributors participating to this project.
*/

using Microsoft.Extensions.Options;

namespace AspNet.Security.OAuth.BattleNet;

/// <summary>
/// A class used to setup defaults for all <see cref="BattleNetAuthenticationOptions"/>.
/// </summary>
public class BattleNetPostConfigureOptions : IPostConfigureOptions<BattleNetAuthenticationOptions>
{
/// <inheritdoc/>
public void PostConfigure(
string? name,
[NotNull] BattleNetAuthenticationOptions options)
{
switch (options.Region)
{
case BattleNetAuthenticationRegion.Unified:
options.AuthorizationEndpoint = BattleNetAuthenticationDefaults.Unified.AuthorizationEndpoint;
options.TokenEndpoint = BattleNetAuthenticationDefaults.Unified.TokenEndpoint;
options.UserInformationEndpoint = BattleNetAuthenticationDefaults.Unified.UserInformationEndpoint;
break;

case BattleNetAuthenticationRegion.America:
options.AuthorizationEndpoint = BattleNetAuthenticationDefaults.America.AuthorizationEndpoint;
options.TokenEndpoint = BattleNetAuthenticationDefaults.America.TokenEndpoint;
options.UserInformationEndpoint = BattleNetAuthenticationDefaults.America.UserInformationEndpoint;
break;

case BattleNetAuthenticationRegion.China:
options.AuthorizationEndpoint = BattleNetAuthenticationDefaults.China.AuthorizationEndpoint;
options.TokenEndpoint = BattleNetAuthenticationDefaults.China.TokenEndpoint;
options.UserInformationEndpoint = BattleNetAuthenticationDefaults.China.UserInformationEndpoint;
break;

case BattleNetAuthenticationRegion.Europe:
options.AuthorizationEndpoint = BattleNetAuthenticationDefaults.Europe.AuthorizationEndpoint;
options.TokenEndpoint = BattleNetAuthenticationDefaults.Europe.TokenEndpoint;
options.UserInformationEndpoint = BattleNetAuthenticationDefaults.Europe.UserInformationEndpoint;
break;

case BattleNetAuthenticationRegion.Korea:
options.AuthorizationEndpoint = BattleNetAuthenticationDefaults.Korea.AuthorizationEndpoint;
options.TokenEndpoint = BattleNetAuthenticationDefaults.Korea.TokenEndpoint;
options.UserInformationEndpoint = BattleNetAuthenticationDefaults.Korea.UserInformationEndpoint;
break;

case BattleNetAuthenticationRegion.Taiwan:
options.AuthorizationEndpoint = BattleNetAuthenticationDefaults.Taiwan.AuthorizationEndpoint;
options.TokenEndpoint = BattleNetAuthenticationDefaults.Taiwan.TokenEndpoint;
options.UserInformationEndpoint = BattleNetAuthenticationDefaults.Taiwan.UserInformationEndpoint;
break;

case BattleNetAuthenticationRegion.Custom:
break; // Do nothing

default:
throw new NotSupportedException($"The BattleNet region '{options.Region}' is not supported.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,45 @@ protected internal override void RegisterAuthentication(AuthenticationBuilder bu

[Theory]
[InlineData(ClaimTypes.NameIdentifier, "my-id")]
[InlineData(ClaimTypes.Name, "John Smith")]
[InlineData(ClaimTypes.Name, "Unified")]
public async Task Can_Sign_In_Using_BattleNet(string claimType, string claimValue)
=> await AuthenticateUserAndAssertClaimValue(claimType, claimValue);

[Theory]
[InlineData(BattleNetAuthenticationRegion.America)]
[InlineData(BattleNetAuthenticationRegion.China)]
[InlineData(BattleNetAuthenticationRegion.Europe)]
[InlineData(BattleNetAuthenticationRegion.Korea)]
[InlineData(BattleNetAuthenticationRegion.Taiwan)]
[InlineData(BattleNetAuthenticationRegion.Unified)]
public async Task Can_Sign_In_Using_BattleNet_Region(BattleNetAuthenticationRegion region)
{
// Arrange
void ConfigureServices(IServiceCollection services)
{
services.AddOptions<BattleNetAuthenticationOptions>(BattleNetAuthenticationDefaults.AuthenticationScheme)
.Configure((options) => options.Region = region);
}

await AuthenticateUserAndAssertClaimValue(ClaimTypes.Name, region.ToString(), ConfigureServices);
}

[Fact]
public async Task Can_Sign_In_Using_Custom_BattleNet_Region()
{
// Arrange
static void ConfigureServices(IServiceCollection services)
{
services.AddOptions<BattleNetAuthenticationOptions>(BattleNetAuthenticationDefaults.AuthenticationScheme)
.Configure((options) =>
{
options.Region = BattleNetAuthenticationRegion.Custom;
options.AuthorizationEndpoint = "https://oauth.battle.local/oauth/authorize";
options.TokenEndpoint = "https://oauth.battle.local/oauth/token";
options.UserInformationEndpoint = "https://oauth.battle.local/oauth/userinfo";
});
}

await AuthenticateUserAndAssertClaimValue(ClaimTypes.Name, "Custom", ConfigureServices);
}
}
Loading

0 comments on commit 8dfccb3

Please sign in to comment.