1
0
mirror of https://github.com/bitwarden/server.git synced 2024-11-24 12:35:25 +01:00

Provide client device type and version info in feature flag contexts (#4755)

This commit is contained in:
Matt Bishop 2024-09-10 12:49:46 -04:00 committed by GitHub
parent ab73eeae16
commit 4f874ff375
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 50 additions and 10 deletions

View File

@ -2,6 +2,7 @@
using Bit.Core.Settings;
using Bit.Core.Utilities;
using LaunchDarkly.Logging;
using LaunchDarkly.Sdk;
using LaunchDarkly.Sdk.Server;
using LaunchDarkly.Sdk.Server.Integrations;
using LaunchDarkly.Sdk.Server.Interfaces;
@ -14,6 +15,16 @@ public class LaunchDarklyFeatureService : IFeatureService
private readonly ICurrentContext _currentContext;
private const string _anonymousUser = "25a15cac-58cf-4ac0-ad0f-b17c4bd92294";
private const string _contextKindOrganization = "organization";
private const string _contextKindServiceAccount = "service-account";
private const string _contextAttributeClientVersion = "client-version";
private const string _contextAttributeClientVersionMajor = "client-version-major";
private const string _contextAttributeClientVersionMinor = "client-version-minor";
private const string _contextAttributeClientVersionBuild = "client-version-build";
private const string _contextAttributeDeviceType = "device-type";
private const string _contextAttributeOrganizations = "organizations";
public LaunchDarklyFeatureService(
ILdClient client,
ICurrentContext currentContext)
@ -110,15 +121,15 @@ public class LaunchDarklyFeatureService : IFeatureService
var value = values.GetFlagValueJson(key);
switch (value.Type)
{
case LaunchDarkly.Sdk.LdValueType.Bool:
case LdValueType.Bool:
results.Add(key, value.AsBool);
break;
case LaunchDarkly.Sdk.LdValueType.Number:
case LdValueType.Number:
results.Add(key, value.AsInt);
break;
case LaunchDarkly.Sdk.LdValueType.String:
case LdValueType.String:
results.Add(key, value.AsString);
break;
}
@ -130,13 +141,29 @@ public class LaunchDarklyFeatureService : IFeatureService
private LaunchDarkly.Sdk.Context BuildContext()
{
void SetCommonContextAttributes(ContextBuilder builder)
{
if (_currentContext.ClientVersion != null)
{
builder.Set(_contextAttributeClientVersion, _currentContext.ClientVersion.ToString());
builder.Set(_contextAttributeClientVersionMajor, _currentContext.ClientVersion.Major);
builder.Set(_contextAttributeClientVersionMinor, _currentContext.ClientVersion.Minor);
builder.Set(_contextAttributeClientVersionBuild, _currentContext.ClientVersion.Build);
}
if (_currentContext.DeviceType.HasValue)
{
builder.Set(_contextAttributeDeviceType, (int)_currentContext.DeviceType.Value);
}
}
var builder = LaunchDarkly.Sdk.Context.MultiBuilder();
switch (_currentContext.ClientType)
{
case Identity.ClientType.User:
{
LaunchDarkly.Sdk.ContextBuilder ldUser;
ContextBuilder ldUser;
if (_currentContext.UserId.HasValue)
{
ldUser = LaunchDarkly.Sdk.Context.Builder(_currentContext.UserId.Value.ToString());
@ -148,12 +175,13 @@ public class LaunchDarklyFeatureService : IFeatureService
ldUser.Anonymous(true);
}
ldUser.Kind(LaunchDarkly.Sdk.ContextKind.Default);
ldUser.Kind(ContextKind.Default);
SetCommonContextAttributes(ldUser);
if (_currentContext.Organizations?.Any() ?? false)
{
var ldOrgs = _currentContext.Organizations.Select(o => LaunchDarkly.Sdk.LdValue.Of(o.Id.ToString()));
ldUser.Set("organizations", LaunchDarkly.Sdk.LdValue.ArrayFrom(ldOrgs));
var ldOrgs = _currentContext.Organizations.Select(o => LdValue.Of(o.Id.ToString()));
ldUser.Set(_contextAttributeOrganizations, LaunchDarkly.Sdk.LdValue.ArrayFrom(ldOrgs));
}
builder.Add(ldUser.Build());
@ -165,7 +193,10 @@ public class LaunchDarklyFeatureService : IFeatureService
if (_currentContext.OrganizationId.HasValue)
{
var ldOrg = LaunchDarkly.Sdk.Context.Builder(_currentContext.OrganizationId.Value.ToString());
ldOrg.Kind("organization");
ldOrg.Kind(_contextKindOrganization);
SetCommonContextAttributes(ldOrg);
builder.Add(ldOrg.Build());
}
}
@ -176,14 +207,20 @@ public class LaunchDarklyFeatureService : IFeatureService
if (_currentContext.UserId.HasValue)
{
var ldServiceAccount = LaunchDarkly.Sdk.Context.Builder(_currentContext.UserId.Value.ToString());
ldServiceAccount.Kind("service-account");
ldServiceAccount.Kind(_contextKindServiceAccount);
SetCommonContextAttributes(ldServiceAccount);
builder.Add(ldServiceAccount.Build());
}
if (_currentContext.OrganizationId.HasValue)
{
var ldOrg = LaunchDarkly.Sdk.Context.Builder(_currentContext.OrganizationId.Value.ToString());
ldOrg.Kind("organization");
ldOrg.Kind(_contextKindOrganization);
SetCommonContextAttributes(ldOrg);
builder.Add(ldOrg.Build());
}
}

View File

@ -2,6 +2,7 @@
using Bit.Core.Context;
using Bit.Core.Services;
using Bit.Core.Settings;
using Bit.Core.Utilities;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
using LaunchDarkly.Sdk.Server.Interfaces;
@ -22,6 +23,8 @@ public class LaunchDarklyFeatureServiceTests
var currentContext = Substitute.For<ICurrentContext>();
currentContext.UserId.Returns(Guid.NewGuid());
currentContext.ClientVersion.Returns(new Version(AssemblyHelpers.GetVersion()));
currentContext.DeviceType.Returns(Enums.DeviceType.ChromeBrowser);
var client = Substitute.For<ILdClient>();