Skip to content

Commit c5a70b3

Browse files
authored
Fix downloading embedded images (#2853)
Fixes #2852 Authentication HTTP header was not set correctly, so images were not downloaded. Requests were failing with 401 Unauthorized response. I tested it for `Windows` authentication mode in source and now it is working correctly. ## Changes - Correctly create token for basic HTTP authorization header based on authentication type. - Removed `sourceWorkItem` parameter from `FixEmbededImages` method, because it was not used.
2 parents 587344a + 6ee5c1a commit c5a70b3

File tree

3 files changed

+23
-20
lines changed

3 files changed

+23
-20
lines changed

src/MigrationTools.Clients.TfsObjectModel/Processors/TfsWorkItemMigrationProcessor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,7 @@ private void ProcessHTMLFieldAttachements(WorkItemData targetWorkItem)
598598
{
599599
if (targetWorkItem != null && Options.FixHtmlAttachmentLinks)
600600
{
601-
CommonTools.EmbededImages.FixEmbededImages(this, null, targetWorkItem);
601+
CommonTools.EmbededImages.FixEmbededImages(this, targetWorkItem);
602602
}
603603
}
604604

src/MigrationTools.Clients.TfsObjectModel/Processors/TfsWorkItemOverwriteProcessor.cs

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,16 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Diagnostics;
4-
using System.Linq;
54
using Microsoft.Extensions.DependencyInjection;
65
using Microsoft.Extensions.Logging;
6+
using Microsoft.Extensions.Options;
77
using Microsoft.TeamFoundation.WorkItemTracking.Client;
8-
using MigrationTools;
9-
using MigrationTools.Clients;
10-
using MigrationTools._EngineV1.Configuration;
11-
using MigrationTools._EngineV1.Configuration.Processing;
128
using MigrationTools._EngineV1.DataContracts;
13-
9+
using MigrationTools.Clients;
1410
using MigrationTools.DataContracts;
15-
using Microsoft.Extensions.Options;
16-
using MigrationTools.Tools;
17-
using MigrationTools.Processors.Infrastructure;
1811
using MigrationTools.Enrichers;
12+
using MigrationTools.Processors.Infrastructure;
13+
using MigrationTools.Tools;
1914

2015
namespace MigrationTools.Processors
2116
{
@@ -69,9 +64,9 @@ protected override void InternalExecute()
6964
{
7065
Log.LogInformation("...Exists");
7166
TfsExtensions.ToWorkItem(targetFound).Open();
72-
CommonTools.FieldMappingTool.ApplyFieldMappings(sourceWI, targetFound);
67+
CommonTools.FieldMappingTool.ApplyFieldMappings(sourceWI, targetFound);
7368
CommonTools.WorkItemEmbededLink.Enrich(this, null, targetFound);
74-
CommonTools.EmbededImages.FixEmbededImages(this, sourceWI, targetFound);
69+
CommonTools.EmbededImages.FixEmbededImages(this, targetFound);
7570
if (TfsExtensions.ToWorkItem(targetFound).IsDirty)
7671
{
7772
try
@@ -105,4 +100,4 @@ protected override void InternalExecute()
105100
}
106101

107102
}
108-
}
103+
}

src/MigrationTools.Clients.TfsObjectModel/Tools/TfsEmbededImagesTool.cs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Net;
55
using System.Net.Http;
66
using System.Net.Http.Headers;
7+
using System.Text;
78
using System.Text.RegularExpressions;
89
using Microsoft.Extensions.Logging;
910
using Microsoft.Extensions.Options;
@@ -12,6 +13,7 @@
1213
using Microsoft.TeamFoundation.WorkItemTracking.WebApi;
1314
using MigrationTools.DataContracts;
1415
using MigrationTools.Endpoints;
16+
using MigrationTools.Options;
1517
using MigrationTools.Processors.Infrastructure;
1618
using MigrationTools.Tools.Infrastructure;
1719

@@ -24,7 +26,6 @@ public class TfsEmbededImagesTool : EmbededImagesRepairToolBase<TfsEmbededImages
2426
private const string TargetDummyWorkItemTitle = "***** DELETE THIS - Migration Tool Generated Dummy Work Item For TfsEmbededImagesTool *****";
2527

2628
private Project _targetProject;
27-
private TfsTeamProjectEndpointOptions _targetConfig;
2829

2930
private readonly IDictionary<string, string> _cachedUploadedUrisBySourceValue;
3031

@@ -35,16 +36,23 @@ public TfsEmbededImagesTool(IOptions<TfsEmbededImagesToolOptions> options, IServ
3536
_cachedUploadedUrisBySourceValue = new System.Collections.Concurrent.ConcurrentDictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
3637
}
3738

38-
39-
public int FixEmbededImages(TfsProcessor processor, WorkItemData sourceWorkItem, WorkItemData targetWorkItem)
39+
public int FixEmbededImages(TfsProcessor processor, WorkItemData targetWorkItem)
4040
{
4141
_processor = processor;
4242
_targetProject = processor.Target.WorkItems.Project.ToProject();
43-
_targetConfig = processor.Target.Options;
44-
FixEmbededImages(targetWorkItem, processor.Source.Options.Collection.AbsoluteUri, processor.Target.Options.Collection.AbsoluteUri, processor.Source.Options.Authentication.AccessToken);
43+
string? accessToken = processor.Source.Options.Authentication.AuthenticationMode switch
44+
{
45+
AuthenticationMode.AccessToken => processor.Source.Options.Authentication.AccessToken,
46+
AuthenticationMode.Windows => GetWindowsAuthToken(processor.Source.Options.Authentication.NetworkCredentials),
47+
_ => null
48+
};
49+
FixEmbededImages(targetWorkItem, processor.Source.Options.Collection.AbsoluteUri, processor.Target.Options.Collection.AbsoluteUri, accessToken);
4550
return 0;
4651
}
4752

53+
private string GetWindowsAuthToken(NetworkCredentials cred)
54+
=> Convert.ToBase64String(Encoding.ASCII.GetBytes($"{cred.Domain}\\{cred.UserName}:{cred.Password}"));
55+
4856
public void ProcessorExecutionEnd(TfsProcessor processor)
4957
{
5058
_processor = processor;
@@ -124,7 +132,7 @@ private string UploadedAndRetrieveAttachmentLinkUrl(string matchedSourceUri, str
124132
{
125133
if (!string.IsNullOrEmpty(sourcePersonalAccessToken))
126134
{
127-
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes(string.Format("{0}:{1}", "", sourcePersonalAccessToken))));
135+
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", sourcePersonalAccessToken);
128136
}
129137
var result = DownloadFile(httpClient, matchedSourceUri, fullImageFilePath);
130138
if (!result.IsSuccessStatusCode)
@@ -182,7 +190,7 @@ private Microsoft.TeamFoundation.WorkItemTracking.WebApi.Models.AttachmentRefere
182190
}
183191

184192
// Attaches it with dummy work item and removes it just to be able to make the image visible to all the users.
185-
// VS402330: Unauthorized Read access to the attachment under the areas
193+
// VS402330: Unauthorized Read access to the attachment under the areas
186194
var payload = new Microsoft.VisualStudio.Services.WebApi.Patch.Json.JsonPatchDocument();
187195
payload.Add(new Microsoft.VisualStudio.Services.WebApi.Patch.Json.JsonPatchOperation()
188196
{

0 commit comments

Comments
 (0)