jekyll-wkd 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a06312e387e2b7da2c7bc5071f2b614a435436c47b883da84430b1d1bbbaeb3f
4
+ data.tar.gz: 60196f579ce1740cab8ae47d787e18f7a0c6badeaf1c679b05926feda5f76446
5
+ SHA512:
6
+ metadata.gz: 9879f889d072ba3d0291105c901aa50b18fca5fa9fb2464af07f8a552bc6d393f818e62f1b6d1eafc5572f5c83656b3da1a579a9851ed8d4b2333ea97fafc913
7
+ data.tar.gz: bac3744510b72721c0c89e34c811af06287151185aaf60f02b92ed9a018e72b81d3227faf7f57e4b342830794a0a0e4d77c4b6b4fae48b864c990f8a68feba54
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "jekyll"
4
+ require "gpgme"
5
+ require "set"
6
+ require "tmpdir"
7
+
8
+ module JekyllWKD
9
+ class Generator < ::Jekyll::Generator
10
+ safe true
11
+ priority :normal
12
+
13
+ CONF_KEY = "wkd"
14
+ CONF_DEFAULT = {
15
+ "path" => "keys",
16
+ "exts" => %w[.asc .pub]
17
+ }
18
+
19
+ def generate site
20
+ @site = site
21
+
22
+ pgp_home = Dir.mktmpdir "jekyll-wkd-"
23
+ GPGME::Engine.home_dir = pgp_home
24
+ Jekyll::Hooks.register :site, :post_write do
25
+ FileUtils.remove_dir pgp_home
26
+ end
27
+
28
+ domains = Set.new
29
+
30
+ key_files.each do |file|
31
+ File.open(file.path) do |data|
32
+ GPGME::Key.import(data).imports.each do |key|
33
+ kf = KeyFile.new(
34
+ @site,
35
+ @site.source,
36
+ File.dirname(file.relative_path),
37
+ File.basename(file.relative_path),
38
+ key.fingerprint
39
+ )
40
+ domains << kf.domain
41
+ @site.static_files << kf
42
+ end
43
+ end
44
+ end
45
+
46
+ domains.each do |domain|
47
+ @site.pages << make_policy(domain)
48
+ end
49
+ end
50
+
51
+ private
52
+
53
+ def config
54
+ @config ||= CONF_DEFAULT.merge @site.config.fetch(CONF_KEY, {})
55
+ end
56
+
57
+ def in_path? file
58
+ File.exist? @site.in_source_dir(config["path"], file.name)
59
+ end
60
+
61
+ def key_files
62
+ @key_files ||= @site.static_files.select do |file|
63
+ in_path?(file) && file.relative_path.end_with?(*config["exts"])
64
+ end
65
+ end
66
+
67
+ def make_policy domain
68
+ path = File.join(PGP_PATH, domain, "policy")
69
+ PolicyFile.new(@site, __dir__, "", path).tap do |page|
70
+ page.content = "# Policy flags for domain `#{domain}`\n"
71
+ page.data.merge!(
72
+ "layout" => nil,
73
+ "sitemap" => false
74
+ )
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JekyllWKD
4
+ module ZBase32
5
+ CHAR = "ybndrfg8ejkmcpqxot1uwisza345h769"
6
+ SIZE = 5
7
+ MASK = (1 << SIZE) - 1
8
+
9
+ def self.encode str
10
+ blocks(str, SIZE).map(&:encode).join
11
+ end
12
+
13
+ def self.blocks str, size
14
+ str.bytes.reverse.each_slice(size).map { |b| Block.new b }.reverse
15
+ end
16
+
17
+ class Block
18
+ def initialize bytes
19
+ @bytes = bytes
20
+ end
21
+
22
+ def encode
23
+ n = -(@bytes.length * -8 / SIZE)
24
+ c = @bytes.reverse.reduce(0) { |a, b| (a << 8) + b }
25
+ (n - 1).downto(0).map { |i| CHAR[(c >> i * SIZE) & MASK] }
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "jekyll"
4
+ require "digest"
5
+
6
+ module JekyllWKD
7
+ class KeyFile < ::Jekyll::StaticFile
8
+ def initialize site, base, dir, name, fpr
9
+ @fpr = fpr
10
+ super site, base, dir, name
11
+ end
12
+
13
+ def destination dest
14
+ @destination ||= {}
15
+ @destination[dest] ||= @site.in_dest_dir(
16
+ dest, PGP_PATH, domain, "hu", hash
17
+ )
18
+ end
19
+
20
+ def write dest
21
+ dest_path = destination dest
22
+ return false if File.exist?(dest_path) && !modified?
23
+
24
+ self.class.mtimes[path] = mtime
25
+
26
+ FileUtils.mkdir_p(File.dirname(dest_path))
27
+ FileUtils.rm(dest_path) if File.exist?(dest_path)
28
+
29
+ File.open(dest_path, "w") { |f| pgpkey.export output: f }
30
+ true
31
+ end
32
+
33
+ def domain
34
+ @domain ||= pgpkey.email.split("@").last
35
+ end
36
+
37
+ def username
38
+ @username || pgpkey.email.split("@").first
39
+ end
40
+
41
+ def hash
42
+ @hash ||= ZBase32.encode Digest::SHA1.digest username
43
+ end
44
+
45
+ private
46
+
47
+ def pgpkey
48
+ @pgpkey ||= GPGME::Key.get(@fpr)
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JekyllWKD
4
+ class PolicyFile < ::Jekyll::Page
5
+ def read_yaml(*)
6
+ @data ||= {}
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JekyllWKD
4
+ VERSION = "1.0.0"
5
+ end
data/lib/jekyll-wkd.rb ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "jekyll-wkd/generator"
4
+
5
+ module JekyllWKD
6
+ PGP_PATH = ".well-known/openpgpkey"
7
+
8
+ autoload :VERSION, "jekyll-wkd/version"
9
+ autoload :ZBase32, "jekyll-wkd/hash"
10
+ autoload :KeyFile, "jekyll-wkd/keyfile"
11
+ autoload :PolicyFile, "jekyll-wkd/policyfile"
12
+ end
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jekyll-wkd
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Fern Zapata
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-06-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: jekyll
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '5.0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '3.0'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '5.0'
33
+ - !ruby/object:Gem::Dependency
34
+ name: gpgme
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '2.0'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '2.0'
47
+ description:
48
+ email:
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - lib/jekyll-wkd.rb
54
+ - lib/jekyll-wkd/generator.rb
55
+ - lib/jekyll-wkd/hash.rb
56
+ - lib/jekyll-wkd/keyfile.rb
57
+ - lib/jekyll-wkd/policyfile.rb
58
+ - lib/jekyll-wkd/version.rb
59
+ homepage: https://github.com/fernzi/jekyll-wkd
60
+ licenses:
61
+ - LGPL-3.0-or-later
62
+ metadata:
63
+ homepage_uri: https://github.com/fernzi/jekyll-wkd
64
+ source_code_uri: https://github.com/fernzi/jekyll-wkd
65
+ post_install_message:
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: 2.6.0
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubygems_version: 3.3.25
81
+ signing_key:
82
+ specification_version: 4
83
+ summary: Jekyll plugin to generate an OpenPGP Web Key Directory (WKD)
84
+ test_files: []