Skip to content
This repository has been archived by the owner on Sep 12, 2022. It is now read-only.

Commit

Permalink
identity huh
Browse files Browse the repository at this point in the history
  • Loading branch information
0xdeafcafe committed Apr 28, 2020
1 parent 86a9f89 commit 2b27761
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 10 deletions.
6 changes: 5 additions & 1 deletion dotnet/Services/Identity/App/Application.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Branch.Services.Identity.Libraries;
using Branch.Services.Identity.Models;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
Expand All @@ -10,16 +11,19 @@ public partial class Application
private ILogger _logger { get; }
private IRedisClientsManager _redisClientsManager { get; }
private Config _config { get; }
private XblIdentityCache _xblIdentityCache { get; }

public Application(
ILoggerFactory loggerFactory,
IRedisClientsManager redisClientsManager,
IOptionsMonitor<Config> options
IOptionsMonitor<Config> options,
XblIdentityCache xblIdentityCache
)
{
_logger = loggerFactory.CreateLogger(typeof(Application));
_redisClientsManager = redisClientsManager;
_config = options.CurrentValue;
_xblIdentityCache = xblIdentityCache;
}
}
}
11 changes: 3 additions & 8 deletions dotnet/Services/Identity/App/GetXblIdentity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,10 @@ public partial class Application

public async Task<GetXblIdentityRes> GetXblIdentity(HttpContext ctx, GetXblIdentityReq req)
{
var useCache = !req.IgnoreCache;
if (req.Type == "gamertag")
return await _xblIdentityCache.GetByGamertag(req.Value, req.IgnoreCache);

using (var client = _redisClientsManager.GetClient())
{
return new GetXblIdentityRes
{
CacheInfo = null,
};
}
return await _xblIdentityCache.GetByGamertag(req.Value, req.IgnoreCache);
}
}
}
107 changes: 107 additions & 0 deletions dotnet/Services/Identity/Libraries/XblIdentityCache.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Branch.Global.Contracts;
using Branch.Global.Extensions;
using Branch.Global.Libraries;
using Branch.Global.Models.XboxLive;
using Branch.Services.Token;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using ServiceStack.Redis;

namespace Branch.Services.Identity.Libraries
{
public class XblIdentityCache
{
private ILogger _logger { get; }
private IRedisClientsManager _redisClientsManager { get; }
private TokenClient _tokenClient { get; }
private JsonClient _client { get; }

private string _authHeader = "XBL3.0 x={0};{1}";
private string _pathTemplate = "/users/{0}({1})/profile/settings";

public XblIdentityCache(
ILoggerFactory loggerFactory,
IRedisClientsManager redisClientsManager,
TokenClient tokenClient
)
{
_logger = loggerFactory.CreateLogger(typeof(XblIdentityCache));
_redisClientsManager = redisClientsManager;
_tokenClient = tokenClient;
_client = new JsonClient("https://profile.xboxlive.com");
}

public async Task<GetXblIdentityRes> GetByGamertag(string gamertag, bool useCache)
{
return await GetIdentity(LookupType.Gamertag, gamertag, useCache);
}

public async Task<GetXblIdentityRes> GetByXuid(string xuid, bool useCache)
{
return await GetIdentity(LookupType.Xuid, xuid, useCache);
}

private async Task<GetXblIdentityRes> GetIdentity(LookupType type, string value, bool useCache)
{
using (var client = _redisClientsManager.GetClient())
{
if (useCache)
{
var ident = client.GetJson<GetXblIdentityRes>(GenerateRedisKey(type, value));
if (ident != null)
return ident;
}

var (gamertag, xuid) = await GetProfileSettings(type, value);
var identity = new GetXblIdentityRes
{
CacheInfo = new CacheInfo(DateTime.UtcNow, TimeSpan.FromMinutes(30)),
Gamertag = gamertag,
Xuid = xuid,
};

var jsonStr = JsonConvert.SerializeObject(identity);
var expiry = (DateTime) identity.CacheInfo.ExpiresAt;

client.Set(GenerateRedisKey(LookupType.Gamertag, gamertag.ToSlug()), jsonStr, expiry);
client.Set(GenerateRedisKey(LookupType.Xuid, xuid), jsonStr, expiry);

return identity;
}
}

private async Task<(string gamertag, string xuid)> GetProfileSettings(LookupType type, string value)
{
var token = await _tokenClient.GetXblToken(null, new GetTokenRequest());
var options = new HttpClientOptions();
var query = new Dictionary<string, string>();
var path = string.Format(_pathTemplate, type.ToString().ToLowerInvariant(), value);

options.Headers.Add("authorization", string.Format(_authHeader, token.Uhs, token.Token));
options.Headers.Add("X-XBL-Contract-Version", "2");
query.Add("settings", "gamertag");

var response = await _client.Do<ProfileSettings>("GET", path, query, options);
var user = response.ProfileUsers[0];
var xuid = user.ID.ToString();
var gamertag = user.Settings.First(s => s.ID == "Gamertag").Value;

return (gamertag, xuid);
}

private string GenerateRedisKey(LookupType type, string value)
{
return $"{type.ToString().ToLowerInvariant()}-{value.Trim().ToSlug()}";
}

private enum LookupType
{
Gamertag,
Xuid
}
}
}
13 changes: 12 additions & 1 deletion dotnet/Services/Identity/Models/Config.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
using System.Collections.Generic;
using Branch.Global.Contracts;
using Branch.Global.Libraries;

namespace Branch.Services.Identity.Models
{
public class Config
Expand All @@ -6,12 +10,19 @@ public class Config

public string RedisConnectionString { get; set; }

public ServiceConfig TokenConfig { get; set; }

public static Config CreateDefault()
{
return new Config
{
InternalKeys = new string[] {"test"},
InternalKeys = new string[] { "test" },
RedisConnectionString = "redis://127.0.0.1:6379?db=1",
TokenConfig = new ServiceConfig
{
Url = "https://service-token.branch.golf",
Key = LocalSecrets.GetConfigValue<string>("prod", "token", "InternalKeys[0]"),
}
};
}
}
Expand Down
6 changes: 6 additions & 0 deletions dotnet/Services/Identity/Startup.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
using System.Threading.Tasks;
using Branch.Global.Attributes;
using Branch.Global.Contracts;
using Branch.Services.Identity.App;
using Branch.Services.Identity.Libraries;
using Branch.Services.Identity.Models;
using Branch.Services.Identity.Server;
using Branch.Services.Token;
using Crpc;
using Crpc.Registration;
using Microsoft.AspNetCore.Builder;
Expand All @@ -27,8 +30,11 @@ public void ConfigureServices(IServiceCollection services)
services.Configure<Config>(Configuration);

var redisConnectionString = Configuration.GetSection("RedisConnectionString").Get<string>();
var tokenCfg = Configuration.GetSection("TokenConfig").Get<ServiceConfig>();

services.AddSingleton<IRedisClientsManager>(new BasicRedisClientManager(redisConnectionString));
services.AddSingleton(new TokenClient(tokenCfg.Url, tokenCfg.Key));
services.AddSingleton<XblIdentityCache>();

services.AddCrpc<Application, RpcServer>(opts =>
{
Expand Down

0 comments on commit 2b27761

Please sign in to comment.