Skip to content

Commit 2e0bf79

Browse files
authored
Add hyperlink validation and refactor CreateHyperlink (#2994)
Refactored `CreateHyperlink` to improve clarity and maintainability. - Changed `sourceLinkAbsoluteUri` declaration to `string`. - Added `IsValidHyperlink` method to validate hyperlink format and protocol. - Introduced `GetAbsoluteUri` method for reusable URI parsing logic. - Enhanced logging to provide detailed warnings for invalid hyperlinks. - Improved code readability by modularizing validation and URI handling.
2 parents bba5d81 + 84c8108 commit 2e0bf79

File tree

1 file changed

+31
-1
lines changed

1 file changed

+31
-1
lines changed

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

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,12 +425,17 @@ private bool IsRelatedLink(Link item)
425425

426426
private void CreateHyperlink(Hyperlink sourceLink, WorkItemData target)
427427
{
428-
var sourceLinkAbsoluteUri = GetAbsoluteUri(sourceLink);
428+
string sourceLinkAbsoluteUri = GetAbsoluteUri(sourceLink);
429429
if (string.IsNullOrEmpty(sourceLinkAbsoluteUri))
430430
{
431431
Log.LogWarning(" [SKIP] Unable to create a hyperlink to [{0}]", sourceLink.Location);
432432
return;
433433
}
434+
if (!IsValidHyperlink(sourceLinkAbsoluteUri))
435+
{
436+
Log.LogWarning(" [SKIP] Unable to create a hyperlink to [{0}] <-- protocall no longer allowed or url format is invalid", sourceLink.Location);
437+
return;
438+
}
434439

435440
var exist = (from hyperlink in target.ToWorkItem().Links.OfType<Hyperlink>()
436441
let absoluteUri = GetAbsoluteUri(hyperlink)
@@ -458,6 +463,8 @@ where string.Equals(sourceLinkAbsoluteUri, absoluteUri, StringComparison.Ordinal
458463
}
459464
}
460465

466+
467+
461468
private string GetAbsoluteUri(Hyperlink hyperlink)
462469
{
463470
try
@@ -489,5 +496,28 @@ private bool IsHyperlink(Link item)
489496
return item is Hyperlink;
490497
}
491498

499+
private bool IsValidHyperlink(string sourceLinkAbsoluteUri)
500+
{
501+
if (string.IsNullOrEmpty(sourceLinkAbsoluteUri))
502+
{
503+
return false;
504+
}
505+
506+
try
507+
{
508+
var uri = new Uri(sourceLinkAbsoluteUri);
509+
var allowedSchemes = new[]
510+
{
511+
"http", "https", "ftp", "gopher", "mailto", "news", "telnet", "wais",
512+
"vstfs", "tfs", "alm", "mtm", "mtms", "mtr", "mtrs", "mfbclient", "mfbclients",
513+
"test-runner", "x-mvwit", "onenote", "codeflow", "file", "tel", "skype"
514+
};
515+
return allowedSchemes.Contains(uri.Scheme.ToLowerInvariant());
516+
}
517+
catch (UriFormatException)
518+
{
519+
return false;
520+
}
521+
}
492522
}
493523
}

0 commit comments

Comments
 (0)