Browse Source

add support for Azure DevOps platform in SCM detection and link (#1807)

* feat: add support for Azure DevOps platform in SCM detection and link generation

* feat: add support for visualstudio.com in Azure DevOps platform detection

* feat: consolidate Azure DevOps platform detection for dev.azure.com and visualstudio.com
Joost Voskuil 10 months ago
parent
commit
af7d5bcb83
4 changed files with 44 additions and 0 deletions
  1. 4 0
      cmd/scm/scm.go
  2. 2 0
      detect/git.go
  3. 12 0
      detect/utils.go
  4. 26 0
      detect/utils_test.go

+ 4 - 0
cmd/scm/scm.go

@@ -12,6 +12,7 @@ const (
 	NoPlatform               // Explicitly disable the feature
 	GitHubPlatform
 	GitLabPlatform
+	AzureDevOpsPlatform
 	// TODO: Add others.
 )
 
@@ -21,6 +22,7 @@ func (p Platform) String() string {
 		"none",
 		"github",
 		"gitlab",
+		"azuredevops",
 	}[p]
 }
 
@@ -34,6 +36,8 @@ func PlatformFromString(s string) (Platform, error) {
 		return GitHubPlatform, nil
 	case "gitlab":
 		return GitLabPlatform, nil
+	case "azuredevops":
+		return AzureDevOpsPlatform, nil
 	default:
 		return UnknownPlatform, fmt.Errorf("invalid scm platform value: %s", s)
 	}

+ 2 - 0
detect/git.go

@@ -171,6 +171,8 @@ func platformFromHost(u *url.URL) scm.Platform {
 		return scm.GitHubPlatform
 	case "gitlab.com":
 		return scm.GitLabPlatform
+	case "dev.azure.com", "visualstudio.com":
+		return scm.AzureDevOpsPlatform
 	default:
 		return scm.UnknownPlatform
 	}

+ 12 - 0
detect/utils.go

@@ -78,6 +78,18 @@ func createScmLink(scmPlatform scm.Platform, remoteUrl string, finding report.Fi
 			link += fmt.Sprintf("-%d", finding.EndLine)
 		}
 		return link
+	case scm.AzureDevOpsPlatform:
+		link := fmt.Sprintf("%s/commit/%s?path=/%s", remoteUrl, finding.Commit, filePath)
+		// Add line information if applicable
+		if finding.StartLine != 0 {
+			link += fmt.Sprintf("&line=%d", finding.StartLine)
+		}
+		if finding.EndLine != finding.StartLine {
+			link += fmt.Sprintf("&lineEnd=%d", finding.EndLine)
+		}
+		// This is a bit dirty, but Azure DevOps does not highlight the line when the lineStartColumn and lineEndColumn are not provided
+		link += "&lineStartColumn=1&lineEndColumn=10000000&type=2&lineStyle=plain&_a=files"
+		return link
 	default:
 		// This should never happen.
 		return ""

+ 26 - 0
detect/utils_test.go

@@ -91,6 +91,32 @@ func Test_createScmLink(t *testing.T) {
 			},
 			want: "https://gitlab.com/example-org/example-group/gitleaks/blob/63410f74e23a4e51e1f60b9feb073b5d325af878/.vscode/launchSettings.json#L6-8",
 		},
+
+		// Azure DevOps
+		"azuredevops - single line": {
+			platform: scm.AzureDevOpsPlatform,
+			url:      "https://dev.azure.com/exampleorganisation/exampleproject/_git/exampleRepository",
+			finding: report.Finding{
+				Commit:    "20553ad96a4a080c94a54d677db97eed8ce2560d",
+				File:      "examplefile.json",
+				StartLine: 25,
+				EndLine:   25,
+			},
+			want: "https://dev.azure.com/exampleorganisation/exampleproject/_git/exampleRepository/commit/20553ad96a4a080c94a54d677db97eed8ce2560d?path=/examplefile.json&line=25&lineStartColumn=1&lineEndColumn=10000000&type=2&lineStyle=plain&_a=files",
+		},
+
+		// Azure DevOps
+		"azuredevops - multi line": {
+			platform: scm.AzureDevOpsPlatform,
+			url:      "https://dev.azure.com/exampleorganisation/exampleproject/_git/exampleRepository",
+			finding: report.Finding{
+				Commit:    "20553ad96a4a080c94a54d677db97eed8ce2560d",
+				File:      "examplefile.json",
+				StartLine: 25,
+				EndLine:   30,
+			},
+			want: "https://dev.azure.com/exampleorganisation/exampleproject/_git/exampleRepository/commit/20553ad96a4a080c94a54d677db97eed8ce2560d?path=/examplefile.json&line=25&lineEnd=30&lineStartColumn=1&lineEndColumn=10000000&type=2&lineStyle=plain&_a=files",
+		},
 	}
 	for name, tt := range tests {
 		t.Run(name, func(t *testing.T) {