Skip to content

Commit 539f061

Browse files
committed
Squash
1 parent 5f55eaf commit 539f061

File tree

694 files changed

+1043
-231
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

694 files changed

+1043
-231
lines changed

.github/workflows/dev_api.yml

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,83 @@ jobs:
2626
with:
2727
persist-credentials: false
2828

29+
- name: Setup PowerShell module cache
30+
id: cacher
31+
uses: actions/cache@v3
32+
with:
33+
path: "~/.local/share/powershell/Modules"
34+
key: ${{ runner.os }}-ModuleBuilder
35+
36+
- name: Install ModuleBuilder
37+
if: steps.cacher.outputs.cache-hit != 'true'
38+
shell: pwsh
39+
run: |
40+
Set-PSRepository PSGallery -InstallationPolicy Trusted
41+
Install-Module ModuleBuilder -AllowClobber -Force
42+
43+
- name: Build CIPPCore Module
44+
shell: pwsh
45+
run: |
46+
$ModulePath = Join-Path $env:GITHUB_WORKSPACE "Modules/CIPPCore"
47+
$OutputPath = Join-Path $env:GITHUB_WORKSPACE "Output"
48+
49+
Write-Host "Building module from: $ModulePath"
50+
Write-Host "Output directory: $OutputPath"
51+
52+
# Build the module using ModuleBuilder
53+
Build-Module -SourcePath $ModulePath -OutputDirectory $OutputPath -Verbose
54+
55+
# Replace the source module with the built module
56+
Remove-Item -Path $ModulePath -Recurse -Force
57+
Copy-Item -Path (Join-Path $OutputPath "CIPPCore") -Destination $ModulePath -Recurse -Force
58+
59+
Write-Host "Module built and replaced successfully"
60+
61+
# Clean up output directory
62+
Remove-Item -Path $OutputPath -Recurse -Force
63+
64+
- name: Build CippExtensions Module
65+
shell: pwsh
66+
run: |
67+
$ModulePath = Join-Path $env:GITHUB_WORKSPACE "Modules/CippExtensions"
68+
$OutputPath = Join-Path $env:GITHUB_WORKSPACE "Output"
69+
70+
Write-Host "Building module from: $ModulePath"
71+
Write-Host "Output directory: $OutputPath"
72+
73+
# Build the module using ModuleBuilder
74+
Build-Module -SourcePath $ModulePath -OutputDirectory $OutputPath -Verbose
75+
76+
# Replace the source module with the built module
77+
Remove-Item -Path $ModulePath -Recurse -Force
78+
Copy-Item -Path (Join-Path $OutputPath "CippExtensions") -Destination $ModulePath -Recurse -Force
79+
80+
Write-Host "Module built and replaced successfully"
81+
82+
# Clean up output directory
83+
Remove-Item -Path $OutputPath -Recurse -Force
84+
85+
- name: Build CIPPStandardsAlerts Module
86+
shell: pwsh
87+
run: |
88+
$ModulePath = Join-Path $env:GITHUB_WORKSPACE "Modules/CIPPStandardsAlerts"
89+
$OutputPath = Join-Path $env:GITHUB_WORKSPACE "Output"
90+
91+
Write-Host "Building module from: $ModulePath"
92+
Write-Host "Output directory: $OutputPath"
93+
94+
# Build the module using ModuleBuilder
95+
Build-Module -SourcePath $ModulePath -OutputDirectory $OutputPath -Verbose
96+
97+
# Replace the source module with the built module
98+
Remove-Item -Path $ModulePath -Recurse -Force
99+
Copy-Item -Path (Join-Path $OutputPath "CIPPStandardsAlerts") -Destination $ModulePath -Recurse -Force
100+
101+
Write-Host "Module built and replaced successfully"
102+
103+
# Clean up output directory
104+
Remove-Item -Path $OutputPath -Recurse -Force
105+
29106
- name: Login to Azure
30107
uses: azure/login@v2
31108
with:

Modules/CIPPCore/CIPPCore.psm1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# ModuleBuilder will concatenate all function files into this module
22
# This block is only used when running from source (not built)
33
if (Test-Path (Join-Path $PSScriptRoot 'Public')) {
4+
# Load Public and Private functions
45
$Public = @(Get-ChildItem -Path (Join-Path $PSScriptRoot 'Public\*.ps1') -Recurse -ErrorAction SilentlyContinue)
56
$Private = @(Get-ChildItem -Path (Join-Path $PSScriptRoot 'Private\*.ps1') -Recurse -ErrorAction SilentlyContinue)
67
$Functions = $Public + $Private

Modules/CIPPCore/Public/Authentication/Test-CIPPAccess.ps1

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,56 +4,54 @@ function Test-CIPPAccess {
44
[switch]$TenantList,
55
[switch]$GroupList
66
)
7-
# Initialize per-call profiling
7+
88
$AccessTimings = @{}
99
$AccessTotalSw = [System.Diagnostics.Stopwatch]::StartNew()
1010
if ($Request.Params.CIPPEndpoint -eq 'ExecSAMSetup') { return $true }
11-
12-
# Get function help
1311
$FunctionName = 'Invoke-{0}' -f $Request.Params.CIPPEndpoint
1412

1513
$SwPermissions = [System.Diagnostics.Stopwatch]::StartNew()
16-
if (-not $global:CIPPFunctionPermissions) {
14+
if (-not $script:CIPPFunctionPermissions) {
1715
$CIPPCoreModule = Get-Module -Name CIPPCore
1816
if ($CIPPCoreModule) {
19-
$PermissionsFileJson = Join-Path $CIPPCoreModule.ModuleBase 'lib' 'data' 'function-permissions.json'
20-
21-
if (Test-Path $PermissionsFileJson) {
17+
$CIPPCoreModuleRoot = $CIPPCoreModule.ModuleBase
18+
$CIPPRoot = (Get-Item $CIPPCoreModuleRoot).Parent.Parent
19+
$MetadataPath = Join-Path $CIPPRoot 'Config\function-metadata.psd1'
20+
if (Test-Path $MetadataPath) {
2221
try {
23-
$jsonData = Get-Content -Path $PermissionsFileJson -Raw | ConvertFrom-Json -AsHashtable
24-
$global:CIPPFunctionPermissions = [System.Collections.Hashtable]::new([StringComparer]::OrdinalIgnoreCase)
25-
foreach ($key in $jsonData.Keys) {
26-
$global:CIPPFunctionPermissions[$key] = $jsonData[$key]
27-
}
28-
Write-Debug "Loaded $($global:CIPPFunctionPermissions.Count) function permissions from JSON cache"
22+
$metadata = Import-PowerShellDataFile -Path $MetadataPath
23+
$script:CIPPFunctionPermissions = $metadata.Functions
24+
Write-Debug "Loaded $($script:CIPPFunctionPermissions.Count) function permissions from metadata cache"
2925
} catch {
30-
Write-Warning "Failed to load function permissions from JSON: $($_.Exception.Message)"
26+
Write-Warning "Failed to load function permissions from metadata: $($_.Exception.Message)"
3127
}
28+
} else {
29+
Write-Warning "Metadata file not found at $MetadataPath"
3230
}
3331
}
3432
}
3533
$SwPermissions.Stop()
3634
$AccessTimings['FunctionPermissions'] = $SwPermissions.Elapsed.TotalMilliseconds
3735

3836
if ($FunctionName -ne 'Invoke-me') {
39-
$swHelp = [System.Diagnostics.Stopwatch]::StartNew()
40-
if ($global:CIPPFunctionPermissions -and $global:CIPPFunctionPermissions.ContainsKey($FunctionName)) {
41-
$PermissionData = $global:CIPPFunctionPermissions[$FunctionName]
37+
$swMeta = [System.Diagnostics.Stopwatch]::StartNew()
38+
if ($script:CIPPFunctionPermissions -and $script:CIPPFunctionPermissions.ContainsKey($FunctionName)) {
39+
$PermissionData = $script:CIPPFunctionPermissions[$FunctionName]
4240
$APIRole = $PermissionData['Role']
4341
$Functionality = $PermissionData['Functionality']
44-
Write-Debug "Loaded function permission data from cache for '$FunctionName': Role='$APIRole', Functionality='$Functionality'"
42+
Write-Debug "Loaded function permission data from metadata for '$FunctionName': Role='$APIRole', Functionality='$Functionality'"
4543
} else {
4644
try {
4745
$Help = Get-Help $FunctionName -ErrorAction Stop
4846
$APIRole = $Help.Role
4947
$Functionality = $Help.Functionality
5048
Write-Debug "Loaded function permission data via Get-Help for '$FunctionName': Role='$APIRole', Functionality='$Functionality'"
5149
} catch {
52-
Write-Warning "Function '$FunctionName' not found"
50+
Write-Warning "Function '$FunctionName' not found in metadata cache or via Get-Help"
5351
}
5452
}
55-
$swHelp.Stop()
56-
$AccessTimings['GetHelp'] = $swHelp.Elapsed.TotalMilliseconds
53+
$swMeta.Stop()
54+
$AccessTimings['MetadataLookup'] = $swMeta.Elapsed.TotalMilliseconds
5755
}
5856

5957
# Get default roles from config
@@ -120,6 +118,13 @@ function Test-CIPPAccess {
120118
}
121119
if ($Request.Params.CIPPEndpoint -eq 'me') {
122120
$Permissions = Get-CippAllowedPermissions -UserRoles $CustomRoles
121+
$swApiClient.Stop()
122+
$AccessTotalSw.Stop()
123+
$AccessTimings['ApiClientBranch'] = $swApiClient.Elapsed.TotalMilliseconds
124+
$AccessTimings['Total'] = $AccessTotalSw.Elapsed.TotalMilliseconds
125+
$AccessTimingsRounded = [ordered]@{}
126+
foreach ($Key in ($AccessTimings.Keys | Sort-Object)) { $AccessTimingsRounded[$Key] = [math]::Round($AccessTimings[$Key], 2) }
127+
Write-Information "#### Access Timings #### $($AccessTimingsRounded | ConvertTo-Json -Compress)"
123128
return ([HttpResponseContext]@{
124129
StatusCode = [HttpStatusCode]::OK
125130
Body = (
@@ -153,6 +158,13 @@ function Test-CIPPAccess {
153158
if ($Request.Params.CIPPEndpoint -eq 'me') {
154159

155160
if (!$User.userRoles) {
161+
$swUserBranch.Stop()
162+
$AccessTotalSw.Stop()
163+
$AccessTimings['UserBranch'] = $swUserBranch.Elapsed.TotalMilliseconds
164+
$AccessTimings['Total'] = $AccessTotalSw.Elapsed.TotalMilliseconds
165+
$AccessTimingsRounded = [ordered]@{}
166+
foreach ($Key in ($AccessTimings.Keys | Sort-Object)) { $AccessTimingsRounded[$Key] = [math]::Round($AccessTimings[$Key], 2) }
167+
Write-Information "#### Access Timings #### $($AccessTimingsRounded | ConvertTo-Json -Compress)"
156168
return ([HttpResponseContext]@{
157169
StatusCode = [HttpStatusCode]::OK
158170
Body = (
@@ -167,6 +179,13 @@ function Test-CIPPAccess {
167179
$Permissions = Get-CippAllowedPermissions -UserRoles $User.userRoles
168180
$swPermsMe.Stop()
169181
$AccessTimings['GetPermissions(me)'] = $swPermsMe.Elapsed.TotalMilliseconds
182+
$swUserBranch.Stop()
183+
$AccessTotalSw.Stop()
184+
$AccessTimings['UserBranch'] = $swUserBranch.Elapsed.TotalMilliseconds
185+
$AccessTimings['Total'] = $AccessTotalSw.Elapsed.TotalMilliseconds
186+
$AccessTimingsRounded = [ordered]@{}
187+
foreach ($Key in ($AccessTimings.Keys | Sort-Object)) { $AccessTimingsRounded[$Key] = [math]::Round($AccessTimings[$Key], 2) }
188+
Write-Information "#### Access Timings #### $($AccessTimingsRounded | ConvertTo-Json -Compress)"
170189
return ([HttpResponseContext]@{
171190
StatusCode = [HttpStatusCode]::OK
172191
Body = (
@@ -465,13 +484,13 @@ function Test-CIPPAccess {
465484
$AccessTimings['Total'] = $AccessTotalSw.Elapsed.TotalMilliseconds
466485
$AccessTimingsRounded = [ordered]@{}
467486
foreach ($Key in ($AccessTimings.Keys | Sort-Object)) { $AccessTimingsRounded[$Key] = [math]::Round($AccessTimings[$Key], 2) }
468-
Write-Debug "#### Access Timings #### $($AccessTimingsRounded | ConvertTo-Json -Compress)"
487+
Write-Information "#### Access Timings #### $($AccessTimingsRounded | ConvertTo-Json -Compress)"
469488
return @('AllTenants')
470489
}
471490
$AccessTotalSw.Stop()
472491
$AccessTimings['Total'] = $AccessTotalSw.Elapsed.TotalMilliseconds
473492
$AccessTimingsRounded = [ordered]@{}
474493
foreach ($Key in ($AccessTimings.Keys | Sort-Object)) { $AccessTimingsRounded[$Key] = [math]::Round($AccessTimings[$Key], 2) }
475-
Write-Debug "#### Access Timings #### $($AccessTimingsRounded | ConvertTo-Json -Compress)"
494+
Write-Information "#### Access Timings #### $($AccessTimingsRounded | ConvertTo-Json -Compress)"
476495
return $true
477496
}

Modules/CIPPCore/Public/Authentication/Test-CIPPAccessUserRole.ps1

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ function Test-CIPPAccessUserRole {
2525
$Roles = @()
2626

2727
# Check AsyncLocal cache first (per-request cache)
28-
if ($script:CippUserRolesStorage -and $script:CippUserRolesStorage.Value -and $script:CippUserRolesStorage.Value.ContainsKey($User.userDetails)) {
29-
$Roles = $script:CippUserRolesStorage.Value[$User.userDetails]
28+
if ($global:CippUserRolesStorage -and $global:CippUserRolesStorage.Value -and $global:CippUserRolesStorage.Value.ContainsKey($User.userDetails)) {
29+
$Roles = $global:CippUserRolesStorage.Value[$User.userDetails]
3030
} else {
3131
# Check table storage cache (persistent cache)
3232
try {
@@ -45,8 +45,8 @@ function Test-CIPPAccessUserRole {
4545
$Roles = $UserRole.Role | ConvertFrom-Json
4646

4747
# Store in AsyncLocal cache for this request
48-
if ($script:CippUserRolesStorage -and $script:CippUserRolesStorage.Value) {
49-
$script:CippUserRolesStorage.Value[$User.userDetails] = $Roles
48+
if ($global:CippUserRolesStorage -and $global:CippUserRolesStorage.Value) {
49+
$global:CippUserRolesStorage.Value[$User.userDetails] = $Roles
5050
}
5151
} else {
5252
try {
@@ -115,8 +115,8 @@ function Test-CIPPAccessUserRole {
115115
}
116116

117117
# Store in AsyncLocal cache for this request
118-
if ($script:CippUserRolesStorage -and $script:CippUserRolesStorage.Value) {
119-
$script:CippUserRolesStorage.Value[$User.userDetails] = $Roles
118+
if ($global:CippUserRolesStorage -and $global:CippUserRolesStorage.Value) {
119+
$global:CippUserRolesStorage.Value[$User.userDetails] = $Roles
120120
}
121121
}
122122
}

Modules/CIPPCore/Public/Entrypoints/Invoke-ListFunctionParameters.ps1

Lines changed: 0 additions & 79 deletions
This file was deleted.

Modules/CIPPCore/Public/GraphHelper/Get-Tenants.ps1

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -275,9 +275,9 @@ function Get-Tenants {
275275
}
276276
}
277277

278-
# Limit tenant list to allowed tenants if set in script scope from New-CippCoreRequest
279-
if ($script:CippAllowedTenantsStorage -and $script:CippAllowedTenantsStorage.Value) {
280-
$IncludedTenantsCache = $IncludedTenantsCache | Where-Object { $script:CippAllowedTenantsStorage.Value -contains $_.customerId }
278+
# Limit tenant list to allowed tenants if set in global scope from New-CippCoreRequest
279+
if ($global:CippAllowedTenantsStorage -and $global:CippAllowedTenantsStorage.Value) {
280+
$IncludedTenantsCache = $IncludedTenantsCache | Where-Object { $global:CippAllowedTenantsStorage.Value -contains $_.customerId }
281281
}
282282

283283
return $IncludedTenantsCache | Where-Object { ($null -ne $_.defaultDomainName -and ($_.defaultDomainName -notmatch 'Domain Error' -or $IncludeAll.IsPresent)) } | Where-Object $IncludedTenantFilter | Sort-Object -Property displayName

Modules/CIPPCore/Public/GraphHelper/New-GraphBulkRequest.ps1

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ function New-GraphBulkRequest {
1818
if ($NoAuthCheck -or (Get-AuthorisedRequest -Uri $uri -TenantID $tenantid)) {
1919
$headers = Get-GraphToken -tenantid $tenantid -scope $scope -AsApp $asapp
2020

21-
if ($script:XMsThrottlePriority) {
22-
$headers['x-ms-throttle-priority'] = $script:XMsThrottlePriority
21+
if ($global:XMsThrottlePriority) {
22+
$headers['x-ms-throttle-priority'] = $global:XMsThrottlePriority
2323
}
2424

2525
$URL = "https://graph.microsoft.com/$Version/`$batch"

Modules/CIPPCore/Public/GraphHelper/New-GraphGetRequest.ps1

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ function New-GraphGetRequest {
3737
$headers['ConsistencyLevel'] = 'eventual'
3838
}
3939

40-
if ($script:XMsThrottlePriority) {
41-
$headers['x-ms-throttle-priority'] = $script:XMsThrottlePriority
40+
if ($global:XMsThrottlePriority) {
41+
$headers['x-ms-throttle-priority'] = $global:XMsThrottlePriority
4242
}
4343

4444
$nextURL = $uri
@@ -85,7 +85,8 @@ function New-GraphGetRequest {
8585
} else {
8686
$GraphRequest.ResponseHeadersVariable = 'ResponseHeaders'
8787
$Data = (Invoke-RestMethod @GraphRequest)
88-
$script:LastGraphResponseHeaders = $ResponseHeaders
88+
# Store response headers in global scope for cross-module access
89+
$global:LastGraphResponseHeaders = $ResponseHeaders
8990
}
9091

9192
# If we reach here, the request was successful

0 commit comments

Comments
 (0)