Skip to content

Commit 1dd31ad

Browse files
refactor(security): move DependencyViolation and ComplianceReport to shared module (#378)
## Summary Resolves #324 Moves inline class definitions from `Test-DependencyPinning.ps1` to a dedicated module for improved reusability and testability. ## Changes ### New: `scripts/security/Modules/SecurityClasses.psm1` - `DependencyViolation` class - represents a single pinning violation - Default constructor - Parameterized constructor for common use cases - `ComplianceReport` class - aggregates violations and generates reports - `AddViolation()` method - `CalculateScore()` method - `ToHashtable()` method for serialization - Full documentation with examples ### Updated: `Test-DependencyPinning.ps1` - Added `using module` import for SecurityClasses.psm1 - Removed ~35 lines of inline class definitions ## Testing - ✅ `npm run lint:ps` - PSScriptAnalyzer passes - ✅ `npm run test:ps` - All Pester tests pass (779 passed) ## Notes Follows the pattern established by `FrontmatterValidation.psm1` in the linting modules. --------- Co-authored-by: Bill Berry <[email protected]> Co-authored-by: Bill Berry <[email protected]>
1 parent 92fce72 commit 1dd31ad

2 files changed

Lines changed: 142 additions & 37 deletions

File tree

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
# Copyright (c) Microsoft Corporation.
2+
# SPDX-License-Identifier: MIT
3+
4+
# SecurityClasses.psm1
5+
#
6+
# Purpose: Shared class definitions for security scanning scripts.
7+
# Author: HVE Core Team
8+
9+
<#
10+
.SYNOPSIS
11+
Shared class definitions for dependency pinning and compliance reporting.
12+
13+
.DESCRIPTION
14+
This module contains class definitions used by security scanning scripts:
15+
- DependencyViolation: Represents a single dependency pinning violation
16+
- ComplianceReport: Aggregates violations and generates compliance reports
17+
18+
.NOTES
19+
Classes must be imported using 'using module' syntax at the top of scripts:
20+
using module ./Modules/SecurityClasses.psm1
21+
#>
22+
23+
class DependencyViolation {
24+
<#
25+
.SYNOPSIS
26+
Represents a single dependency pinning violation.
27+
28+
.DESCRIPTION
29+
Contains information about a dependency that is not properly SHA-pinned,
30+
including file location, dependency details, and remediation guidance.
31+
#>
32+
33+
[string]$File
34+
[int]$Line
35+
[string]$Type
36+
[string]$Name
37+
[string]$Version
38+
[string]$CurrentRef
39+
[string]$Severity
40+
[string]$Description
41+
[string]$Remediation
42+
[hashtable]$Metadata
43+
44+
DependencyViolation() {
45+
$this.Metadata = @{}
46+
}
47+
48+
DependencyViolation(
49+
[string]$File,
50+
[int]$Line,
51+
[string]$Type,
52+
[string]$Name,
53+
[string]$Severity,
54+
[string]$Description
55+
) {
56+
$this.File = $File
57+
$this.Line = $Line
58+
$this.Type = $Type
59+
$this.Name = $Name
60+
$this.Severity = $Severity
61+
$this.Description = $Description
62+
$this.Metadata = @{}
63+
}
64+
}
65+
66+
class ComplianceReport {
67+
<#
68+
.SYNOPSIS
69+
Aggregates dependency violations and generates compliance reports.
70+
71+
.DESCRIPTION
72+
Collects violations from dependency scans and provides metrics like
73+
compliance score, total dependencies, and summary by type.
74+
#>
75+
76+
[string]$ScanPath
77+
[datetime]$Timestamp
78+
[int]$TotalFiles
79+
[int]$ScannedFiles
80+
[int]$TotalDependencies
81+
[int]$PinnedDependencies
82+
[int]$UnpinnedDependencies
83+
[decimal]$ComplianceScore
84+
[DependencyViolation[]]$Violations
85+
[hashtable]$Summary
86+
[hashtable]$Metadata
87+
88+
ComplianceReport() {
89+
$this.Timestamp = Get-Date
90+
$this.Violations = @()
91+
$this.Summary = @{}
92+
$this.Metadata = @{}
93+
}
94+
95+
ComplianceReport([string]$ScanPath) {
96+
$this.ScanPath = $ScanPath
97+
$this.Timestamp = Get-Date
98+
$this.Violations = @()
99+
$this.Summary = @{}
100+
$this.Metadata = @{}
101+
}
102+
103+
[void] AddViolation([DependencyViolation]$Violation) {
104+
$this.Violations += $Violation
105+
$this.UnpinnedDependencies = $this.Violations.Count
106+
}
107+
108+
[void] CalculateScore() {
109+
if ($this.TotalDependencies -gt 0) {
110+
$this.ComplianceScore = [math]::Round(
111+
($this.PinnedDependencies / $this.TotalDependencies) * 100, 2
112+
)
113+
}
114+
else {
115+
$this.ComplianceScore = 100.0
116+
}
117+
}
118+
119+
[hashtable] ToHashtable() {
120+
return @{
121+
ScanPath = $this.ScanPath
122+
Timestamp = $this.Timestamp.ToString('yyyy-MM-ddTHH:mm:ss.fffZ')
123+
TotalFiles = $this.TotalFiles
124+
ScannedFiles = $this.ScannedFiles
125+
TotalDependencies = $this.TotalDependencies
126+
PinnedDependencies = $this.PinnedDependencies
127+
UnpinnedDependencies = $this.UnpinnedDependencies
128+
ComplianceScore = $this.ComplianceScore
129+
Violations = $this.Violations
130+
Summary = $this.Summary
131+
Metadata = $this.Metadata
132+
}
133+
}
134+
}
135+
136+
# Classes are exported automatically when imported via 'using module' syntax.
137+
# No functions to export.
138+
Export-ModuleMember -Function @()

scripts/security/Test-DependencyPinning.ps1

Lines changed: 4 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@
8484
https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-third-party-actions
8585
#>
8686

87+
# Import security classes from shared module
88+
using module ./Modules/SecurityClasses.psm1
89+
8790
[CmdletBinding()]
8891
param(
8992
[Parameter(Mandatory = $false)]
@@ -163,43 +166,7 @@ $DependencyPatterns = @{
163166
}
164167
}
165168

166-
class DependencyViolation {
167-
[string]$File
168-
[int]$Line
169-
[string]$Type
170-
[string]$Name
171-
[string]$Version
172-
[string]$CurrentRef
173-
[string]$Severity
174-
[string]$Description
175-
[string]$Remediation
176-
[hashtable]$Metadata
177-
178-
DependencyViolation() {
179-
$this.Metadata = @{}
180-
}
181-
}
182-
183-
class ComplianceReport {
184-
[string]$ScanPath
185-
[datetime]$Timestamp
186-
[int]$TotalFiles
187-
[int]$ScannedFiles
188-
[int]$TotalDependencies
189-
[int]$PinnedDependencies
190-
[int]$UnpinnedDependencies
191-
[decimal]$ComplianceScore
192-
[DependencyViolation[]]$Violations
193-
[hashtable]$Summary
194-
[hashtable]$Metadata
195-
196-
ComplianceReport() {
197-
$this.Timestamp = Get-Date
198-
$this.Violations = @()
199-
$this.Summary = @{}
200-
$this.Metadata = @{}
201-
}
202-
}
169+
# DependencyViolation and ComplianceReport classes moved to ./Modules/SecurityClasses.psm1
203170

204171
function Test-ShellDownloadSecurity {
205172
<#

0 commit comments

Comments
 (0)