saro-dat 4.3.0 → 4.3.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1bc8964419d2aa39030dbec0e990d8a22d1fa29a8f8eec15235f69e70fa81054
4
- data.tar.gz: e2fb45d1bbb981ea6745fab4661db4f1db41063fe73bc147cd33276c60e4a0fa
3
+ metadata.gz: 56415a92654a73befef882b2ca36674095155444492b8e8c8db99ebb4c3cd7cb
4
+ data.tar.gz: 670ad624aa1372b2d33f1bae79b877b462970ec20e4a40d1419dd12b3fceb27a
5
5
  SHA512:
6
- metadata.gz: c306baa43850bc77ebd33a2c1717f1aaac63ca0c98b538da28cb8ca064e0ed475b0c2e866fee5b47700a49009c085621c5b21f1b989041028e0a481112092590
7
- data.tar.gz: c75ede02ecff59c9e18a85116247eb3bae95c594940f8fedec457434a8f9c9dc9690667d1be103cb4abf03b18c483997a9f0fe4b6adbbb3f3e19c644ad9e66e2
6
+ metadata.gz: '087cad97ce30b7d51e1e0ebed1c30749fd33c59e5cb7ccad1d197e21502f0d5e341fb713f937cd8315b0a56e5d94e1170a061d1967ce8778ec2e926ac7535b19'
7
+ data.tar.gz: a1c460e69d89564b6628d4b264d9f523133c350f0769caae6dff8b401822be8de59223889d9baf8cf7ed535acf15f1698852d60cc2e40da04a26dec4b587d7a4
@@ -0,0 +1,187 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+ require 'uri'
5
+ require 'logger'
6
+ require 'thread'
7
+ require_relative 'dat_manager'
8
+ require_relative 'dat'
9
+
10
+ module Saro
11
+ module Dat
12
+ class DatCmsManager
13
+ DAT_CMS_API_VERSION = "v1"
14
+
15
+ def initialize(uri:, token:, interval_seconds: 60, verify_only: false, dat_manager: nil)
16
+ @uri = uri
17
+ @token = token
18
+ @interval_seconds = interval_seconds
19
+ @verify_only = verify_only
20
+ @manager = dat_manager || DatManager.new
21
+ @version = 0
22
+ @lock = Mutex.new
23
+ @stopped = false
24
+ @logger = Logger.new($stdout)
25
+ @logger.level = Logger::DEBUG
26
+
27
+ sync
28
+
29
+ if @interval_seconds > 0
30
+ schedule_sync
31
+ end
32
+ end
33
+
34
+ def stop
35
+ @lock.synchronize do
36
+ @stopped = true
37
+ @thread&.kill # 혹은 다른 방식으로 스레드 중지
38
+ end
39
+ end
40
+
41
+ def sync
42
+ # non-blocking lock
43
+ unless @lock.try_lock
44
+ @logger.warn("Last request ignored (Duplicate request)")
45
+ return
46
+ end
47
+
48
+ begin
49
+ url = URI("#{@uri}?version=#{@version}")
50
+ request = Net::HTTP::Get.new(url)
51
+ request["Authorization"] = @token
52
+
53
+ response = Net::HTTP.start(url.host, url.port, use_ssl: url.scheme == 'https', open_timeout: 10, read_timeout: 10) do |http|
54
+ http.request(request)
55
+ end
56
+
57
+ if response.code != "200"
58
+ @logger.error("Response status error, status:#{response.code} in #{url}")
59
+ return
60
+ end
61
+
62
+ body = response.body
63
+ if body.nil? || body.empty?
64
+ @logger.debug("No new certificate: #{url}")
65
+ return
66
+ end
67
+
68
+ lines = body.split("\n", 2)
69
+ if lines.length < 2
70
+ if body.start_with?("\n")
71
+ @logger.error("Invalid response: #{url}")
72
+ return
73
+ end
74
+ @logger.debug("No new certificate: #{url}")
75
+ return
76
+ end
77
+
78
+ new_version_str = lines[0].strip
79
+ new_certificates = lines[1].strip
80
+
81
+ if new_version_str.empty?
82
+ @logger.error("Invalid version in response: #{url}")
83
+ return
84
+ end
85
+
86
+ begin
87
+ new_version = Integer(new_version_str)
88
+ renew_count = @manager.imports(new_certificates, clear: false)
89
+ @version = new_version
90
+ @logger.debug("Renewed #{renew_count} certificates for version #{new_version}: #{url}")
91
+ rescue ArgumentError => e
92
+ @logger.error("Failed to parse version or certificates: #{e.message}")
93
+ end
94
+
95
+ rescue StandardError => e
96
+ @logger.error("[Exception] DAT CMS Sync #{@uri}: #{e.message}")
97
+ ensure
98
+ @lock.unlock
99
+ end
100
+ end
101
+
102
+ def get_manager
103
+ @manager
104
+ end
105
+
106
+ def issue(plain, secure)
107
+ @manager.issue(plain, secure)
108
+ end
109
+
110
+ def parse(dat)
111
+ @manager.parse(dat)
112
+ end
113
+
114
+ def self.builder
115
+ DatCmsManagerBuilder.new
116
+ end
117
+
118
+ private
119
+
120
+ def schedule_sync
121
+ @thread = Thread.new do
122
+ loop do
123
+ sleep(@interval_seconds)
124
+ break if @stopped
125
+ run_sync_task
126
+ end
127
+ end
128
+ end
129
+
130
+ def run_sync_task
131
+ sync
132
+ rescue StandardError => e
133
+ @logger.error("Error in sync task: #{e.message}")
134
+ end
135
+ end
136
+
137
+ class DatCmsManagerBuilder
138
+ def initialize
139
+ @uri = "http://localhost:8088"
140
+ @token = ""
141
+ @verify_only = false
142
+ @interval_seconds = 60
143
+ end
144
+
145
+ def uri(uri)
146
+ @uri = uri.delete_suffix('/')
147
+ self
148
+ end
149
+
150
+ def token(token)
151
+ @token = token
152
+ self
153
+ end
154
+
155
+ def verify_only(verify_only)
156
+ @verify_only = verify_only
157
+ self
158
+ end
159
+
160
+ def interval_seconds(interval_seconds)
161
+ @interval_seconds = interval_seconds
162
+ self
163
+ end
164
+
165
+ def build
166
+ parsed = URI.parse(@uri)
167
+
168
+ if parsed.path && parsed.path != '' && parsed.path != '/'
169
+ raise ArgumentError, "uri must be path-less: #{@uri}"
170
+ end
171
+ if parsed.query
172
+ raise ArgumentError, "uri must be query-less: #{@uri}"
173
+ end
174
+
175
+ path = @verify_only ? "/v1/certs/verify-only" : "/v1/certs"
176
+ final_uri = "#{parsed.scheme}://#{parsed.host}:#{parsed.port}#{path}"
177
+
178
+ DatCmsManager.new(
179
+ uri: final_uri,
180
+ token: @token,
181
+ interval_seconds: @interval_seconds,
182
+ verify_only: @verify_only
183
+ )
184
+ end
185
+ end
186
+ end
187
+ end
data/lib/saro-dat.rb CHANGED
@@ -6,7 +6,7 @@ require_relative 'saro/dat/signature'
6
6
  require_relative 'saro/dat/dat_certificate'
7
7
  require_relative 'saro/dat/dat'
8
8
  require_relative 'saro/dat/dat_manager'
9
- require_relative 'saro/dat/cms_manager'
9
+ require_relative 'saro/dat/dat_cms_manager'
10
10
 
11
11
  module Saro
12
12
  module Dat
data/saro-dat.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = "saro-dat"
5
- spec.version = "4.3.0"
5
+ spec.version = "4.3.1"
6
6
  spec.authors = ["marker"]
7
7
  spec.email = ["j@saro.me"]
8
8
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: saro-dat
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.3.0
4
+ version: 4.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - marker
@@ -127,6 +127,7 @@ files:
127
127
  - lib/saro/dat/crypto.rb
128
128
  - lib/saro/dat/dat.rb
129
129
  - lib/saro/dat/dat_certificate.rb
130
+ - lib/saro/dat/dat_cms_manager.rb
130
131
  - lib/saro/dat/dat_manager.rb
131
132
  - lib/saro/dat/signature.rb
132
133
  - lib/saro/dat/util.rb