Class: Capsium::Package::Security
- Inherits:
-
Object
- Object
- Capsium::Package::Security
show all
- Extended by:
- Forwardable
- Defined in:
- lib/capsium/package/security.rb,
sig/capsium/package/security.rbs
Overview
Loads, generates and verifies security.json (ARCHITECTURE.md
section 6). Checksums cover every file in the package except
security.json itself and signature.sig.
Defined Under Namespace
Classes: ChecksumMismatch, IntegrityError, MissingFile, UncheckedFile
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
Constructor Details
#initialize(path, config = nil) ⇒ Security
Returns a new instance of Security.
38
39
40
41
|
# File 'lib/capsium/package/security.rb', line 38
def initialize(path, config = nil)
@path = path
@config = config || load_config
end
|
Instance Attribute Details
Returns the value of attribute config.
34
35
36
|
# File 'lib/capsium/package/security.rb', line 34
def config
@config
end
|
#path ⇒ String
Returns the value of attribute path.
34
35
36
|
# File 'lib/capsium/package/security.rb', line 34
def path
@path
end
|
Class Method Details
.checksums_for(package_path) ⇒ Hash[String, String]
56
57
58
59
60
|
# File 'lib/capsium/package/security.rb', line 56
def self.checksums_for(package_path)
package_files(package_path).sort.to_h do |relative_path|
[relative_path, Digest::SHA256.file(File.join(package_path, relative_path)).hexdigest]
end
end
|
.excluded?(relative_path) ⇒ Boolean
70
71
72
|
# File 'lib/capsium/package/security.rb', line 70
def self.excluded?(relative_path)
[SECURITY_FILE, SIGNATURE_FILE].include?(relative_path)
end
|
.generate(package_path, digital_signatures: nil) ⇒ Security
43
44
45
46
47
48
49
50
51
52
53
54
|
# File 'lib/capsium/package/security.rb', line 43
def self.generate(package_path, digital_signatures: nil)
config = SecurityConfig.new(
security: SecurityData.new(
integrity_checks: IntegrityChecks.new(
checksum_algorithm: "SHA-256",
checksums: checksums_for(package_path)
),
digital_signatures: digital_signatures
)
)
new(File.join(package_path, SECURITY_FILE), config)
end
|
.package_files(package_path) ⇒ Array[String]
62
63
64
65
66
67
68
|
# File 'lib/capsium/package/security.rb', line 62
def self.package_files(package_path)
files = Dir.glob(File.join(package_path, "**", "*")).select do |file|
File.file?(file)
end
files.map { |file| file.delete_prefix("#{package_path}/") }
.reject { |relative_path| excluded?(relative_path) }
end
|
Instance Method Details
#checksums ⇒ Hash[String, String]
89
90
91
|
# File 'lib/capsium/package/security.rb', line 89
def checksums
present? ? config.checksums : {}
end
|
The declared digitalSignatures block, or nil when absent.
79
80
81
82
83
|
# File 'lib/capsium/package/security.rb', line 79
def digital_signatures
return unless present? && config.security
config.security.digital_signatures
end
|
#present? ⇒ Boolean
74
75
76
|
# File 'lib/capsium/package/security.rb', line 74
def present?
!@config.nil?
end
|
#save_to_file(output_path = @path) ⇒ void
This method returns an undefined value.
112
113
114
|
# File 'lib/capsium/package/security.rb', line 112
def save_to_file(output_path = @path)
File.write(output_path, to_json)
end
|
#signed? ⇒ Boolean
85
86
87
|
# File 'lib/capsium/package/security.rb', line 85
def signed?
!digital_signatures&.signature_file.nil?
end
|
#to_hash ⇒ Hash[String, untyped]
69
|
# File 'sig/capsium/package/security.rbs', line 69
def to_hash: () -> Hash[String, untyped]
|
#to_json ⇒ String
68
|
# File 'sig/capsium/package/security.rbs', line 68
def to_json: (*untyped args) -> String
|
93
94
95
96
97
98
99
100
101
102
|
# File 'lib/capsium/package/security.rb', line 93
def verify(package_path)
expected = checksums
errors = verify_present_files(package_path, expected)
expected.each do |relative_path, checksum|
next if File.file?(File.join(package_path, relative_path))
errors << MissingFile.new(path: relative_path, expected: checksum)
end
errors
end
|
#verify!(package_path) ⇒ void
This method returns an undefined value.
104
105
106
107
108
109
110
|
# File 'lib/capsium/package/security.rb', line 104
def verify!(package_path)
errors = verify(package_path)
return if errors.empty?
raise IntegrityError,
"Package integrity check failed: #{errors.map(&:path).join(', ')}"
end
|