secretmgr 0.1.0 → 0.2.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.
@@ -1,200 +1,247 @@
1
- # frozen_string_literal: true
2
-
3
- require "pathname"
4
-
5
- module Secretmgr
6
- # 秘匿情報マネージャ
7
- class Secretmgr
8
- attr_reader :decrypted_text, :secret
9
-
10
- class << self
11
- def create(secret_dir_pn, plain_setting_file_pn, plain_secret_file_pn)
12
- @inst = Secretmgr.new(secret_dir_pn)
13
- @inst.set_setting_for_data(plain_setting_file_pn, plain_secret_file_pn)
14
- @inst
15
- end
16
- end
17
-
18
- def initialize(secret_dir_pn)
19
- @content = nil
20
- @secret_dir_pn = secret_dir_pn
21
- @encrypted_setting_file_pn = "#{@secret_dir_pn}setting.yml"
22
-
23
- @format_config = Config.new(@secret_dir_pn, "format.txt")
24
- home_dir = ENV["HOME"]
25
- @home_pn = Pathname.new(home_dir)
26
- # pemフォーマットの公開鍵ファイルの内容を取得
27
- path = File.join(home_dir, ".ssh", "pem")
28
- pub_key = File.read(path)
29
- # 鍵をOpenSSLのオブジェクトにする
30
- @public_key = OpenSSL::PKey::RSA.new(pub_key)
31
- path = File.join(home_dir, ".ssh", "id_rsa_no")
32
- private_key = File.read(path)
33
- @private_key = OpenSSL::PKey::RSA.new(private_key)
34
-
35
- @mode = OpenSSL::PKey::RSA::PKCS1_PADDING
36
- end
37
-
38
- def set_setting_for_data(plain_setting_file_pn, plain_secret_file_pn)
39
- @plain_setting_file_pn = plain_setting_file_pn
40
- @plain_secret_file_pn = plain_secret_file_pn
41
- @plain_dir_pn = @plain_setting_file_pn.parent
42
- end
43
-
44
- def setup
45
- setup_setting
46
- setup_secret
47
- setup_secret_for_json_file
48
- end
49
-
50
- def setup_setting
51
- content = File.read(@plain_setting_file_pn)
52
- @setting = Ykxutils.yaml_load_compati(content)
53
- # content = YAML.dump(@setting)
54
- encrypted_text = encrypt_with_public_key(content)
55
- dest_setting_file_pn = make_pair_file_pn(@secret_dir_pn, @plain_setting_file_pn, "yml")
56
-
57
- File.write(dest_setting_file_pn, encrypted_text)
58
- end
59
-
60
- def make_pair_file_pn(dest_dir_pn, file_pn, ext)
61
- basename = file_pn.basename
62
- extname = basename.extname
63
- return nil if extname == ext
64
-
65
- basename = file_pn.basename(".*")
66
- dest_dir_pn + %(#{basename}.#{ext})
67
- end
68
-
69
- def setup_secret
70
- plaintext = File.read(@plain_secret_file_pn)
71
- encrypted_text = encrypt_with_common_key(plaintext, @setting["key"], @setting["iv"])
72
- dest_secret_file_pn = make_pair_file_pn(@secret_dir_pn, @plain_secret_file_pn, "yml")
73
- dest_secret_file_pn.realpath
74
- # puts "setup_secret dest_secret_file_pn=#{dest_secret_file_pn}"
75
- # puts "real_pn=#{real_pn}"
76
- File.write(dest_secret_file_pn, encrypted_text)
77
- end
78
-
79
- def setup_secret_for_json_file
80
- top_pn = "#{@plain_dir_pn}JSON_FILE"
81
- top_pn.find do |x|
82
- # p x if x.file?
83
- relative_path = x.relative_path_from(@plain_dir_pn)
84
- # p relative_path
85
- encrypt_and_copy(x, @secret_dir_pn, relative_path)
86
- end
87
- end
88
-
89
- def encrypt_and_copy(src_pn, dest_top_dir_pn, relative_path)
90
- dest_pn = dest_top_dir_pn + relative_path
91
- return unless src_pn.exist? && src_pn.file?
92
-
93
- puts "e_adn_c #{src_pn} -> #{dest_pn}"
94
- plaintext = File.read(src_pn)
95
- encrypted_text = encrypt_with_common_key(plaintext, @setting["key"], @setting["iv"])
96
- File.write(dest_pn, encrypted_text)
97
- end
98
-
99
- def set_setting_for_query(*dirs)
100
- @valid_dirs = dirs.flatten.reject(&:nil?)
101
- @target, @sub_target, _tmp = @valid_dirs
102
- # p "@valid_dirs=#{@valid_dirs}"
103
- @file_format = @format_config.file_format(@target, @sub_target)
104
- p "@file_format=#{@file_format}"
105
- p "dirs=#{dirs}"
106
- @encrypted_secret_file_pn = @format_config.get_file_path(@secret_dir_pn, dirs)
107
- end
108
-
109
- def load_setting
110
- encrypted_text = File.read(@encrypted_setting_file_pn)
111
- # puts "encrypted_text=#{encrypted_text}"
112
- decrypted_text = decrypt_with_private_key(encrypted_text)
113
- setting = YAML.safe_load(decrypted_text)
114
- @key = setting["key"]
115
- @iv = setting["iv"]
116
- # p "load_settings @key=#{@key}"
117
- # p "load_settings @iv=#{@iv}"
118
- end
119
-
120
- def load_secret
121
- base64_text = File.read(@encrypted_secret_file_pn)
122
- encrypted_content = Base64.decode64(base64_text)
123
- begin
124
- @decrpyted_content = decrypt_with_common_key(encrypted_content, @key, @iv)
125
- @content = case @file_format
126
- when "JSON_FILE"
127
- @decrpyted_content
128
- when "YAML"
129
- @secret = YAML.safe_load(@decrpyted_content)
130
- @sub_target ? @secret[@target][@sub_target] : @secret[@target]
131
- else
132
- ""
133
- end
134
- rescue StandardError => e
135
- puts e
136
- puts e.message
137
- puts e.backtrace
138
- puts "Can't dencrypt #{@encrypted_setting_file_pn}"
139
- end
140
- @content
141
- end
142
-
143
- def load
144
- load_setting
145
- load_secret
146
- end
147
-
148
- def encrypt_with_public_key(data)
149
- Base64.encode64(
150
- @public_key.public_encrypt(
151
- data,
152
- OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING
153
- )
154
- ).delete("\n")
155
- end
156
-
157
- def decrypt_with_private_key(base64_text)
158
- @private_key.private_decrypt(
159
- Base64.decode64(base64_text),
160
- OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING
161
- )
162
- end
163
-
164
- # 引数 str を暗号化した結果を返す
165
- def encrypt_with_common_key(plaintext, key, _ivalue)
166
- encx = OpenSSL::Cipher.new(CIPHER_NAME)
167
- encx.encrypt
168
- encx.key = key
169
- encx.iv = ivvalue
170
- # str に与えた文字列を暗号化します。
171
- encrypted_text = encx.update(plaintext) + encx.final
172
-
173
- Base64.encode64(encrypted_text)
174
- end
175
-
176
- def decrypt_with_common_key(encrypted_data, key, ivalue)
177
- decx = OpenSSL::Cipher.new(CIPHER_NAME)
178
- decx.decrypt
179
- decx.key = key
180
- decx.iv = ivalue
181
- data = decx.update(encrypted_data)
182
- final_data = decx.final
183
- decrypted_data = data + final_data
184
- decrypted_data.force_encoding("UTF-8")
185
- end
186
-
187
- def make(_template_dir, _target, _sub_target)
188
- case @file_format
189
- when "JSON_FILE"
190
- @content
191
- when "YAML"
192
- @content.map do |item|
193
- %(export #{item[0]}=#{item[1]})
194
- end.flatten
195
- else
196
- ""
197
- end
198
- end
199
- end
200
- end
1
+ # frozen_string_literal: true
2
+
3
+ require "pathname"
4
+ require "debug"
5
+
6
+ module Secretmgr
7
+ # 秘匿情報マネージャ
8
+ class Secretmgr
9
+ attr_reader :decrypted_text, :secret
10
+
11
+ @log_level = nil
12
+ @init_count = 0
13
+ # @setting_file = "setting.yml"
14
+ JSON_FILE_DIR = "JSON_FILE"
15
+ SETTING_KEY = "key"
16
+ SETTING_IV = "iv"
17
+ FORMAT_JSON = "JSON_FILE"
18
+ FORMAT_YAML = "YAML"
19
+ YML = "yml"
20
+ # @dot_yml = "yml"
21
+ # @secret_dir = "secret"
22
+ DEFAULT_PRIVATE_KEYFILE = ".ssh/id_rsa"
23
+ DEFAULT_PUBLIC_KEYFILE = ".ssh/id_rsa.pub"
24
+
25
+ class << self
26
+ def log_init(log_level)
27
+ return unless @log_level.nil?
28
+
29
+ @log_level = log_level
30
+ Loggerxs.init("log_", "log.txt", ".", true, log_level) if @init_count.zero?
31
+ @init_count += 1
32
+ end
33
+
34
+ def reset_init_count
35
+ @init_count = 0
36
+ end
37
+ end
38
+
39
+ def initialize(seting, secret_dir_pn, secret_key_dir_pn, ope,
40
+ public_keyfile_pn: nil, private_keyfile_pn: nil)
41
+ log_level = :info
42
+ # log_level = :debug
43
+ Secretmgr.log_init(log_level)
44
+
45
+ @setting = seting
46
+ home_pn = Pathname.new(Dir.home)
47
+ secret_dir_pn = Pathname.new(secret_dir_pn) unless secret_dir_pn.instance_of?(Pathname)
48
+ secret_key_dir_pn = Pathname.new(secret_key_dir_pn) unless secret_key_dir_pn.instance_of?(Pathname)
49
+ secret_key_dir_pn.mkdir unless secret_key_dir_pn.exist?
50
+ default_public_keyfile_pn = secret_key_dir_pn + "id_rsa.pub"
51
+ default_private_keyfile_pn = secret_key_dir_pn + "id_rsa"
52
+ public_keyfile_pn = Pathname.new(public_keyfile_pn) if public_keyfile_pn
53
+ private_keyfile_pn = Pathname.new(private_keyfile_pn) if private_keyfile_pn
54
+
55
+ @secret = Secret.new(@setting, home_pn, secret_dir_pn, ope,
56
+ default_public_keyfile_pn,
57
+ default_private_keyfile_pn,
58
+ public_keyfile_pn: public_keyfile_pn,
59
+ private_keyfile_pn: private_keyfile_pn)
60
+ end
61
+
62
+ def valid?
63
+ @secret.valid
64
+ # Loggerxs.debug "1 ret=#{ret}"
65
+ # p "2 ret=#{ret}"
66
+ end
67
+
68
+ def output_public_key(public_keyfile_pn)
69
+ @secret.output_public_key(public_keyfile_pn)
70
+ end
71
+
72
+ def create_public_key(public_keyfile_pn)
73
+ @secret.create_public_key(public_keyfile_pn)
74
+ end
75
+
76
+ def output_private_key(private_keyfile_pn)
77
+ @secret.output_private_key(private_keyfile_pn)
78
+ end
79
+
80
+ def create_private_key(private_keyfile_pn)
81
+ @secret.create_private_key(private_keyfile_pn)
82
+ end
83
+
84
+ def set_setting_for_plain(plain_setting_file_pn, plain_secret_file_pn)
85
+ @plain_setting_file_pn = Pathname.new(@plain_setting_file_pn) if @plain_setting_file_pn
86
+ @plain_setting_file_pn ||= Pathname.new(plain_setting_file_pn)
87
+ @plain_secret_file_pn = Pathname.new(@plain_secret_file_pn) if @plain_secret_file_pn
88
+ @plain_secret_file_pn ||= Pathname.new(plain_secret_file_pn)
89
+ @plain_dir_pn = @plain_setting_file_pn.parent
90
+ @encrypted_setting_file_pn = @secret.encrypted_setting_file_pn
91
+ @encrypted_secret_file_pn = @secret.encrypted_secret_file_pn
92
+ end
93
+
94
+ def set_setting_for_encrypted(encrypted_setting_file_pn, encrypted_secret_file_pn)
95
+ @encrypted_setting_file_pn = Pathname.new(encrypted_setting_file_pn)
96
+ @encrypted_secret_file_pn = Pathname.new(encrypted_secret_file_pn)
97
+ end
98
+
99
+ def setup
100
+ # p "###### setup_setting"
101
+ setup_setting
102
+ # p "###### setup_secret"
103
+ setup_secret
104
+ # p "###### setup_secret_for_json_file"
105
+ setup_secret_for_json_file
106
+ end
107
+
108
+ def setup_setting
109
+ content = File.read(@plain_setting_file_pn)
110
+ # p "setup_setting content.size=#{content.size}"
111
+ # p "setup_setting content=#{content}"
112
+
113
+ @setting = YAML.safe_load(content)
114
+ # p "setup_setting @setting=#{@setting}"
115
+
116
+ Loggerxs.debug @setting
117
+ # pp "@setting=#{@setting}"
118
+ # puts "setup_setting @setting=#{@setting}"
119
+ encrypted_text = @secret.encrypt_with_public_key(content)
120
+ # puts "setup_setting encrypted_text.size=#{encrypted_text.size}"
121
+ # puts "setup_setting encrypted_text=#{encrypted_text}"
122
+ #
123
+ @secret.decrypt_with_private_key(encrypted_text)
124
+ # puts "setup_setting decrypted_text=#{decrypted_text}"
125
+ # puts "setup_setting decrypted_text.size=#{decrypted_text.size}"
126
+
127
+ dest_setting_file_pn = @secret.make_pair_file_pn(@plain_setting_file_pn, YML)
128
+
129
+ Loggerxs.debug "setup_setting dest_setting_file_pn=#{dest_setting_file_pn}"
130
+ File.write(dest_setting_file_pn, encrypted_text)
131
+ # p "dest_setting_file_pn=#{dest_setting_file_pn}"
132
+ end
133
+
134
+ def setup_secret
135
+ plaintext = File.read(@plain_secret_file_pn)
136
+ # puts "setup_secret @setting=#{@setting}"
137
+ encrypted_text = @secret.encrypt_with_common_key(plaintext,
138
+ @setting[SETTING_KEY],
139
+ @setting[SETTING_IV])
140
+ dest_secret_file_pn = @secret.make_pair_file_pn(@plain_secret_file_pn, YML)
141
+ Loggerxs.debug "setup_secret dest_secret_file_pn=#{dest_secret_file_pn}"
142
+ File.write(dest_secret_file_pn, encrypted_text)
143
+ end
144
+
145
+ def remove_last_extension(pathn)
146
+ parent = pathn.parent
147
+ basename = pathn.basename
148
+ ext = basename.extname
149
+ base = basename.basename(ext)
150
+ parent + base
151
+ end
152
+
153
+ def setup_secret_for_json_file
154
+ top_pn = @plain_dir_pn + JSON_FILE_DIR
155
+ top_pn.find do |x|
156
+ next if x.directory?
157
+
158
+ relative_path = x.relative_path_from(@plain_dir_pn)
159
+ new_relative_path = remove_last_extension(relative_path)
160
+ Loggerxs.debug("################ relative_path=#{relative_path}")
161
+ Loggerxs.debug("################ new_relative_path=#{new_relative_path}")
162
+ @secret.encrypt_and_copy(x, new_relative_path, @setting[SETTING_KEY], @setting[SETTING_IV])
163
+ end
164
+ end
165
+
166
+ def set_setting_for_query(*dirs)
167
+ @valid_dirs = dirs.flatten.compact
168
+ @target, @sub_target, _tmp = @valid_dirs
169
+ # p "@valid_dirs=#{@valid_dirs}"
170
+ @file_format = @secret.file_format(@target, @sub_target)
171
+ Loggerxs.debug "@secret_dir_pn=#{@secret_dir_pn}"
172
+ Loggerxs.debug "dirs=#{dirs}"
173
+ Loggerxs.debug "@encrypted_secret_file_pn=#{@encrypted_secret_file_pn}"
174
+
175
+ @encrypted_secret_file_pn = @secret.get_file_path(dirs)
176
+ end
177
+
178
+ def load_setting
179
+ Loggerxs.debug "load_setting @encrypted_setting_file_pn=#{@encrypted_setting_file_pn}"
180
+ encrypted_text = File.read(@encrypted_setting_file_pn)
181
+ Loggerxs.debug "load_setting encrypted_text=#{encrypted_text}"
182
+ decrypted_text = @secret.decrypt_with_private_key(encrypted_text)
183
+ setting = YAML.safe_load(decrypted_text)
184
+ @key = setting[SETTING_KEY]
185
+ Loggerxs.debug "load_setting @key=#{@key}"
186
+ @iv = setting[SETTING_IV]
187
+ Loggerxs.debug "load_setting @iv=#{@iv}"
188
+ end
189
+
190
+ def load_and_decrypt
191
+ Loggerxs.debug("@encrypted_secret_file_pn=#{@encrypted_secret_file_pn}")
192
+ base64_text = File.read(@encrypted_secret_file_pn)
193
+ encrypted_content = Base64.decode64(base64_text)
194
+ begin
195
+ @decrpyted_content = @secret.decrypt_with_common_key(encrypted_content, @key, @iv)
196
+ @content = case @file_format
197
+ when FORMAT_JSON
198
+ @decrpyted_content
199
+ when FORMAT_YAML
200
+ @secret_content = YAML.safe_load(@decrpyted_content)
201
+ @sub_target ? @secret_content[@target][@sub_target] : @secret_content[@target]
202
+ else
203
+ ""
204
+ end
205
+ rescue StandardError => e
206
+ Loggerxs.error e
207
+ Loggerxs.error e.message
208
+ Loggerxs.error e.backtrace
209
+ Loggerxs.error "Can't dencrypt #{@encrypted_setting_file_pn}"
210
+ end
211
+ @content
212
+ end
213
+
214
+ def load
215
+ load_setting
216
+ load_and_decrypt
217
+ end
218
+
219
+ def make(_target, _sub_target)
220
+ case @file_format
221
+ when FORMAT_JSON
222
+ @content
223
+ when FORMAT_YAML
224
+ @content.map do |item|
225
+ %(export #{item[0]}=#{item[1]})
226
+ end.flatten
227
+ else
228
+ ""
229
+ end
230
+ end
231
+
232
+ def valid_private_keyfile(path, default_path = DEFAULT_PRIVATE_KEYFILE)
233
+ valid_pathname(path, default_path)
234
+ end
235
+
236
+ def valid_public_keyfile(path, default_path = DEFAULT_PUBLIC_KEYFILE)
237
+ valid_pathname(path, default_path)
238
+ end
239
+
240
+ def valid_pathname(path, default_path)
241
+ pathn = path
242
+ pathn = Pathname.new(Dir.home) + default_path if Util.nil_or_dontexist?(path)
243
+ pathn = nil if Util.nil_or_dontexist?(pathn)
244
+ pathn
245
+ end
246
+ end
247
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Secretmgr
4
+ class Util
5
+ class << self
6
+ def nil_or_dontexist?(pathn)
7
+ pathn.nil? || !pathn.exist?
8
+ end
9
+
10
+ def nil_or_zero?(str)
11
+ str.nil? || str.empty?
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Secretmgr
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
data/lib/secretmgr.rb CHANGED
@@ -1,22 +1,28 @@
1
- # frozen_string_literal: true
2
-
3
- require "openssl"
4
- require "base64"
5
- require "multi_json"
6
- require "ykxutils"
7
- require "ykutils"
8
-
9
- require_relative "secretmgr/version"
10
- require_relative "secretmgr/secretmgr"
11
- require_relative "secretmgr/config"
12
-
13
- module Secretmgr
14
- INSTALLED_APP = "installed"
15
- WEB_APP = "web"
16
- CLIENT_ID = "client_id"
17
- CLIENT_SECRET = "client_secret"
18
- CIPHER_NAME = "AES-256-CBC"
19
-
20
- class Error < StandardError; end
21
- # Your code goes here...
22
- end
1
+ # frozen_string_literal: true
2
+
3
+ require "openssl"
4
+ require "base64"
5
+ require "multi_json"
6
+
7
+ require "loggerx"
8
+ require_relative "secretmgr/version"
9
+ require_relative "secretmgr/util"
10
+ require_relative "secretmgr/globalsetting"
11
+ require_relative "secretmgr/cli"
12
+ require_relative "secretmgr/secretmgr"
13
+ require_relative "secretmgr/config"
14
+ require_relative "secretmgr/secret"
15
+ require_relative "secretmgr/loggerxs"
16
+ # require_relative "secretmgr/loggerxs"
17
+
18
+ module Secretmgr
19
+ INSTALLED_APP = "installed"
20
+ WEB_APP = "web"
21
+ CLIENT_ID = "client_id"
22
+ CLIENT_SECRET = "client_secret"
23
+ CIPHER_NAME = "AES-256-CBC"
24
+
25
+ class Error < StandardError; end
26
+
27
+ # Your code goes here...
28
+ end
data/rubocoprefine.bat CHANGED
@@ -1,30 +1,30 @@
1
- REMM メソッド定義やメソッド呼び出しの()をいい感じに
2
- rubocop -a --only Style/DefWithParentheses,\
3
- Style/MethodCallParentheses,\
4
- Style/MethodDefParentheses
5
-
6
- REM インデント崩れを修正
7
- rubocop -a --only Style/IndentationConsistency,\
8
- Style/IndentationWidth,\
9
- Style/MultilineOperationIndentation
10
-
11
- REM 空行をいい感じに
12
- rubocop -a --only Style/EmptyLineBetweenDefs,\
13
- Style/EmptyLines,\
14
- Style/EmptyLinesAroundAccessModifier,\
15
- Style/EmptyLinesAroundBlockBody,\
16
- Style/EmptyLinesAroundClassBody,\
17
- Style/EmptyLinesAroundMethodBody,\
18
- Style/EmptyLinesAroundModuleBody,\
19
- Style/TrailingBlankLines
20
-
21
- REM コロンやカンマの前後のスペースをいい感じにする
22
- rubocop -a --only Style/SpaceAfterColon,\
23
- Style/SpaceAfterComma,\
24
- Style/SpaceAfterNot,\
25
- Style/SpaceAfterSemicolon,\
26
- Style/SpaceAroundEqualsInParameterDefault,\
27
- Style/SpaceBeforeSemicolon
28
-
29
- REM 行末のスペース削除
1
+ REMM メソッド定義やメソッド呼び出しの()をいい感じに
2
+ rubocop -a --only Style/DefWithParentheses,\
3
+ Style/MethodCallParentheses,\
4
+ Style/MethodDefParentheses
5
+
6
+ REM インデント崩れを修正
7
+ rubocop -a --only Style/IndentationConsistency,\
8
+ Style/IndentationWidth,\
9
+ Style/MultilineOperationIndentation
10
+
11
+ REM 空行をいい感じに
12
+ rubocop -a --only Style/EmptyLineBetweenDefs,\
13
+ Style/EmptyLines,\
14
+ Style/EmptyLinesAroundAccessModifier,\
15
+ Style/EmptyLinesAroundBlockBody,\
16
+ Style/EmptyLinesAroundClassBody,\
17
+ Style/EmptyLinesAroundMethodBody,\
18
+ Style/EmptyLinesAroundModuleBody,\
19
+ Style/TrailingBlankLines
20
+
21
+ REM コロンやカンマの前後のスペースをいい感じにする
22
+ rubocop -a --only Style/SpaceAfterColon,\
23
+ Style/SpaceAfterComma,\
24
+ Style/SpaceAfterNot,\
25
+ Style/SpaceAfterSemicolon,\
26
+ Style/SpaceAroundEqualsInParameterDefault,\
27
+ Style/SpaceBeforeSemicolon
28
+
29
+ REM 行末のスペース削除
30
30
  rubocop -a --only Style/TrailingWhitespace