-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path02_Inheritance.ps1
More file actions
119 lines (103 loc) · 4.42 KB
/
02_Inheritance.ps1
File metadata and controls
119 lines (103 loc) · 4.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
<#
.SYNOPSIS
OOP Reference: Inheritance Deep Dive
.DESCRIPTION
Topic: Inheritance, Constructor Chaining, Method Override, Type Checking
Category: Fundamentals
Agent Task: Add Pester tests. Add a third level of inheritance (GrandchildCrypto).
Override Describe() in the grandchild with a call to ([AesService]$this).Describe().
Done Conditions:
- Three-level chain loads and instantiates without error
- $grandchild -is [CryptoBase] returns $true
- Pester covers: base ctor called, override fires, is-a chain, safe downcast
- Tests pass: Invoke-Pester -Output Detailed
Non-Scope:
- No multiple inheritance attempts
- No static methods on derived classes yet (covered in factory file)
#>
# ---------------------------------------------------------------------------
# Base class — defines shared state and enforced interface
# ---------------------------------------------------------------------------
class CryptoBase {
[string]$Algorithm
[int]$KeyBits
[datetime]$CreatedAt
CryptoBase([string]$algo, [int]$bits) {
$this.Algorithm = $algo
$this.KeyBits = $bits
$this.CreatedAt = [datetime]::UtcNow
}
# Abstract-equivalent: derived classes must override
[byte[]] Encrypt([byte[]]$data) {
throw [System.NotImplementedException]::new(
"$($this.GetType().Name) must implement Encrypt()")
}
[string] Describe() {
return "$($this.GetType().Name) | $($this.Algorithm) | $($this.KeyBits)-bit | created $($this.CreatedAt.ToString('u'))"
}
}
# ---------------------------------------------------------------------------
# Level 1: AesService — implements Encrypt, chains to base ctor
# ---------------------------------------------------------------------------
class AesService : CryptoBase {
hidden [byte[]]$_key
AesService() : base('AES-256-GCM', 256) {
$this._key = [byte[]]::new(32)
[System.Security.Cryptography.RandomNumberGenerator]::Fill($this._key)
}
AesService([byte[]]$key) : base('AES-256-GCM', $key.Length * 8) {
if ($key.Length -notin @(16, 24, 32)) {
throw [System.ArgumentException]'Key must be 128, 192, or 256 bits'
}
$this._key = $key
}
[byte[]] Encrypt([byte[]]$data) {
$gcm = [System.Security.Cryptography.AesGcm]::new($this._key)
$nonce = [byte[]]::new(12)
$ct = [byte[]]::new($data.Length)
$tag = [byte[]]::new(16)
[System.Security.Cryptography.RandomNumberGenerator]::Fill($nonce)
$gcm.Encrypt($nonce, $data, $ct, $tag)
$gcm.Dispose()
return $nonce + $tag + $ct
}
}
# ---------------------------------------------------------------------------
# Level 2: AuditedAesService — wraps Encrypt with audit, calls base impl
# ---------------------------------------------------------------------------
class AuditedAesService : AesService {
[System.Collections.Generic.List[string]]$AuditLog
AuditedAesService() : base() {
$this.AuditLog = [System.Collections.Generic.List[string]]::new()
}
[byte[]] Encrypt([byte[]]$data) {
$this.AuditLog.Add("ENCRYPT | $(Get-Date -Format u) | $($data.Length) bytes")
return ([AesService]$this).Encrypt($data)
}
}
# ---------------------------------------------------------------------------
# Level 3: GrandchildCrypto — third level demonstrating deep inheritance chain
# ---------------------------------------------------------------------------
class GrandchildCrypto : AuditedAesService {
[string]$Purpose
GrandchildCrypto() : base() {
$this.Purpose = "Deep inheritance demonstration"
}
GrandchildCrypto([string]$purpose) : base() {
$this.Purpose = $purpose
}
# Override Describe() with safe downcast to AesService
[string] Describe() {
$baseDesc = ([AesService]$this).Describe()
return "$baseDesc | Purpose: $($this.Purpose)"
}
}
# ---------------------------------------------------------------------------
# Type-checking utilities (use in Pester or interactive sessions)
# ---------------------------------------------------------------------------
# $svc = [AuditedAesService]::new()
# $svc -is [AuditedAesService] -> $true
# $svc -is [AesService] -> $true
# $svc -is [CryptoBase] -> $true
# $svc.GetType().Name -> AuditedAesService
# $svc.GetType().BaseType.Name -> AesService