Class: Kotoshu::Integrity::Manifest
- Inherits:
-
Object
- Object
- Kotoshu::Integrity::Manifest
- Defined in:
- lib/kotoshu/integrity/manifest.rb
Overview
Parsed view of a content repo’s ‘manifest.json`.
Format (per TODO.impl/09-integrity-security.md task 1):
{
"version": 1,
"generated_at": "2026-06-25T10:00:00Z",
"resources": {
"en/spelling/index.dic": {
"size": 49568,
"sha256": "ab12...",
"language": "en",
"type": "spelling",
"license": "LGPL/MPL/GPL",
"source": "SCROLL"
}
}
}
Construction:
manifest = Manifest.parse(json_string)
manifest.fetch("en/spelling/index.dic") # => Entry or nil
manifest.verify_content!("en/spelling/index.dic", bytes) # raises on mismatch
‘Manifest.load(url, http:)`, returns nil when the manifest 404s (graceful degradation — see module docs).
Defined Under Namespace
Classes: Entry
Instance Attribute Summary collapse
-
#entries ⇒ Object
readonly
Returns the value of attribute entries.
-
#generated_at ⇒ Object
readonly
Returns the value of attribute generated_at.
-
#version ⇒ Object
readonly
Returns the value of attribute version.
Class Method Summary collapse
-
.load(url, http: Kotoshu::Integrity::NetHTTP) ⇒ Object
Fetch and parse a manifest from a URL.
-
.parse(json) ⇒ Object
Parse a manifest JSON string.
Instance Method Summary collapse
- #empty? ⇒ Boolean
- #fetch(path) ⇒ Object
-
#initialize(entries, version: nil, generated_at: nil) ⇒ Manifest
constructor
A new instance of Manifest.
-
#verify_content!(path, content, url: nil) ⇒ Object
Verify that content for ‘path` matches the manifest entry.
Constructor Details
#initialize(entries, version: nil, generated_at: nil) ⇒ Manifest
Returns a new instance of Manifest.
82 83 84 85 86 |
# File 'lib/kotoshu/integrity/manifest.rb', line 82 def initialize(entries, version: nil, generated_at: nil) @entries = entries @version = version @generated_at = generated_at end |
Instance Attribute Details
#entries ⇒ Object (readonly)
Returns the value of attribute entries.
80 81 82 |
# File 'lib/kotoshu/integrity/manifest.rb', line 80 def entries @entries end |
#generated_at ⇒ Object (readonly)
Returns the value of attribute generated_at.
80 81 82 |
# File 'lib/kotoshu/integrity/manifest.rb', line 80 def generated_at @generated_at end |
#version ⇒ Object (readonly)
Returns the value of attribute version.
80 81 82 |
# File 'lib/kotoshu/integrity/manifest.rb', line 80 def version @version end |
Class Method Details
.load(url, http: Kotoshu::Integrity::NetHTTP) ⇒ Object
Fetch and parse a manifest from a URL. Returns nil when the manifest is absent (HTTP 404/410) so callers can fall back to unverified downloads — see module docs. Any other failure (5xx, network error, parse error) raises.
73 74 75 76 77 78 |
# File 'lib/kotoshu/integrity/manifest.rb', line 73 def self.load(url, http: Kotoshu::Integrity::NetHTTP) body = http.get(url) return nil if body.nil? parse(body) end |
.parse(json) ⇒ Object
Parse a manifest JSON string. Returns an empty Manifest if the JSON is parseable but has no resources (caller treats as “no constraints”).
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/kotoshu/integrity/manifest.rb', line 46 def self.parse(json) data = JSON.parse(json) entries = {} (data["resources"] || {}).each do |path, fields| entries[path] = Entry.new( path: path, sha256: fields["sha256"], size: fields["size"], language: fields["language"], type: fields["type"], license: fields["license"], source: fields["source"] ) end new(entries, version: data["version"], generated_at: data["generated_at"]) rescue JSON::ParserError => e raise Kotoshu::IntegrityError.new( "manifest", expected: "<valid JSON>", actual: "<parse error: #{e.}>" ) end |
Instance Method Details
#empty? ⇒ Boolean
92 93 94 |
# File 'lib/kotoshu/integrity/manifest.rb', line 92 def empty? @entries.empty? end |
#fetch(path) ⇒ Object
88 89 90 |
# File 'lib/kotoshu/integrity/manifest.rb', line 88 def fetch(path) @entries[path] end |
#verify_content!(path, content, url: nil) ⇒ Object
Verify that content for ‘path` matches the manifest entry. Raises Kotoshu::IntegrityError on mismatch. No-op when the manifest has no entry for `path` (returns nil — caller decides whether to treat absence as failure in strict mode).
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/kotoshu/integrity/manifest.rb', line 100 def verify_content!(path, content, url: nil) entry = @entries[path] return nil unless entry actual = Digest::SHA256.hexdigest(content) unless actual == entry.sha256 raise Kotoshu::IntegrityError.new( path, expected: entry.sha256, actual: actual, url: url ) end true end |