Skip to content

Commit d24d8fe

Browse files
Mask URL with credentials on publish telemetry
1 parent 42229c7 commit d24d8fe

File tree

3 files changed

+62
-3
lines changed

3 files changed

+62
-3
lines changed

src/Agent.Worker/JobExtension.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -747,7 +747,7 @@ private void PublishKnobsInfo(IExecutionContext jobContext)
747747
var value = knob.GetValue(jobContext);
748748
if (value.Source.GetType() != typeof(BuiltInDefaultKnobSource))
749749
{
750-
var stringValue = value.AsString();
750+
var stringValue = HostContext.SecretMasker.MaskSecrets(value.AsString());
751751
telemetryData.Add($"{knob.Name}-{value.Source.GetDisplayString()}", stringValue);
752752
}
753753
}

src/Test/L0/TestHostContext.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ public TestHostContext(object testClass, [CallerMemberName] string testName = ""
7676
_secretMasker.AddValueEncoder(ValueEncoders.JsonStringEscape);
7777
_secretMasker.AddValueEncoder(ValueEncoders.UriDataEscape);
7878
_secretMasker.AddValueEncoder(ValueEncoders.BackslashEscape);
79+
_secretMasker.AddRegex(AdditionalMaskingRegexes.UrlSecretPattern);
7980
_traceManager = new TraceManager(traceListener, _secretMasker);
8081
_trace = GetTrace(nameof(TestHostContext));
8182

src/Test/L0/Worker/JobExtensionL0.cs

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
using Xunit;
1313
using System.Threading;
1414
using Pipelines = Microsoft.TeamFoundation.DistributedTask.Pipelines;
15+
using Microsoft.VisualStudio.Services.Agent.Worker.Telemetry;
16+
using Microsoft.VisualStudio.Services.WebPlatform;
1517

1618
namespace Microsoft.VisualStudio.Services.Agent.Tests.Worker
1719
{
@@ -61,6 +63,8 @@ public override void InitializeJobExtension(IExecutionContext context, IList<Pip
6163
private Mock<IPagingLogger> _logger;
6264
private Mock<IExpressionManager> _express;
6365
private Mock<IContainerOperationProvider> _containerProvider;
66+
private Mock<ICustomerIntelligenceServer> _mockCiService;
67+
private Mock<IAsyncCommandContext> _asyncCommandContext;
6468
private TestHostContext CreateTestContext(CancellationTokenSource _tokenSource, [CallerMemberName] String testName = "")
6569
{
6670
var hc = new TestHostContext(this, testName);
@@ -291,6 +295,9 @@ private TestHostContext CreateMSITestContext(CancellationTokenSource _tokenSourc
291295
_express = new Mock<IExpressionManager>();
292296
_containerProvider = new Mock<IContainerOperationProvider>();
293297
_logPlugin = new Mock<IAgentLogPlugin>();
298+
_mockCiService = new Mock<ICustomerIntelligenceServer>();
299+
_asyncCommandContext = new Mock<IAsyncCommandContext>();
300+
294301

295302
TaskRunner step1 = new TaskRunner();
296303
TaskRunner step2 = new TaskRunner();
@@ -333,7 +340,7 @@ private TestHostContext CreateMSITestContext(CancellationTokenSource _tokenSourc
333340
Url = new Uri("https://test.visualstudio.com"),
334341
Authorization = new EndpointAuthorization()
335342
{
336-
Scheme = "ManagedServiceIdentity",
343+
Scheme = "OAuth",
337344
}
338345
};
339346
environment.SystemConnection.Authorization.Parameters["AccessToken"] = "token";
@@ -462,6 +469,7 @@ private TestHostContext CreateMSITestContext(CancellationTokenSource _tokenSourc
462469
hc.SetSingleton(_express.Object);
463470
hc.SetSingleton(_containerProvider.Object);
464471
hc.SetSingleton(_logPlugin.Object);
472+
hc.SetSingleton(_mockCiService.Object);
465473
hc.EnqueueInstance<IPagingLogger>(_logger.Object); // jobcontext logger
466474
hc.EnqueueInstance<IPagingLogger>(_logger.Object); // init step logger
467475
hc.EnqueueInstance<IPagingLogger>(_logger.Object); // step 1
@@ -762,5 +770,55 @@ public async Task JobExtensionManagementScriptStepMSI()
762770
Environment.SetEnvironmentVariable("VSTS_AGENT_CLEANUP_INTERNAL_TEMP_HACK", "");
763771
}
764772
}
773+
[Fact]
774+
[Trait("Level", "L0")]
775+
[Trait("Category", "Worker")]
776+
[Trait("SkipOn", "darwin")]
777+
[Trait("SkipOn", "linux")]
778+
public async Task JobExtensionTelemetryPublisherSecretValue()
779+
{
780+
using CancellationTokenSource tokenSource = new CancellationTokenSource();
781+
using TestHostContext hc = CreateMSITestContext(tokenSource);
782+
783+
hc.EnqueueInstance<IAsyncCommandContext>(_asyncCommandContext.Object);
784+
hc.EnqueueInstance<IAsyncCommandContext>(_asyncCommandContext.Object);
785+
hc.EnqueueInstance<IAsyncCommandContext>(_asyncCommandContext.Object);
786+
787+
hc.SetSingleton(new TaskRestrictionsChecker() as ITaskRestrictionsChecker);
788+
789+
Environment.SetEnvironmentVariable("http_proxy", "http://admin:[email protected]");
790+
Environment.SetEnvironmentVariable("AGENT_DISABLE_NODE6_TASKS", "true");
791+
792+
var expectedEvents = new List<Dictionary<string, object>>()
793+
{
794+
new Dictionary<string, object>() { { "JobId", "" }, { "ImageVersion", null } },
795+
new Dictionary<string, object>() {
796+
{ "JobId", null },
797+
{ "ProxyAddress-${http_proxy}", "http://admin:***@localhost.com"},
798+
{ "DisableNode6Tasks-${AGENT_DISABLE_NODE6_TASKS}","true"}
799+
}
800+
};
801+
802+
var actualEvents = new List<CustomerIntelligenceEvent[]>();
803+
804+
_mockCiService.Setup(s => s.PublishEventsAsync(It.IsAny<CustomerIntelligenceEvent[]>()))
805+
.Callback<CustomerIntelligenceEvent[]>(actualEvents.Add)
806+
.Returns(Task.CompletedTask);
807+
808+
809+
TestJobExtension testExtension = new TestJobExtension();
810+
testExtension.Initialize(hc);
811+
List<IStep> result = await testExtension.InitializeJob(_jobEc, _message);
812+
813+
Assert.Equal(expectedEvents.Count, actualEvents.Count);
814+
for (int i = 0; i < expectedEvents.Count; i++)
815+
{
816+
Assert.True(
817+
expectedEvents[i].Count == actualEvents[i][0].Properties.Count &&
818+
!expectedEvents[i].Except(actualEvents[i][0].Properties).Any(),
819+
$"Event at index {i} does not match. "
820+
);
821+
}
822+
}
765823
}
766-
}
824+
}

0 commit comments

Comments
 (0)