s7 0.0.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.
Files changed (44) hide show
  1. data/ChangeLog +311 -0
  2. data/LICENCE +24 -0
  3. data/README +56 -0
  4. data/Rakefile +128 -0
  5. data/VERSION +1 -0
  6. data/bin/s7cli +27 -0
  7. data/lib/gettext.rb +28 -0
  8. data/lib/s7.rb +12 -0
  9. data/lib/s7/action.rb +7 -0
  10. data/lib/s7/attribute.rb +226 -0
  11. data/lib/s7/cipher.rb +110 -0
  12. data/lib/s7/configuration.rb +41 -0
  13. data/lib/s7/entry.rb +106 -0
  14. data/lib/s7/entry_collection.rb +44 -0
  15. data/lib/s7/entry_template.rb +10 -0
  16. data/lib/s7/exception.rb +116 -0
  17. data/lib/s7/file.rb +77 -0
  18. data/lib/s7/gpass_file.rb +202 -0
  19. data/lib/s7/key.rb +83 -0
  20. data/lib/s7/message_catalog.rb +5 -0
  21. data/lib/s7/s7_file.rb +47 -0
  22. data/lib/s7/s7cli.rb +213 -0
  23. data/lib/s7/s7cli/attribute_command.rb +69 -0
  24. data/lib/s7/s7cli/command.rb +210 -0
  25. data/lib/s7/s7cli/entry_collection_command.rb +63 -0
  26. data/lib/s7/s7cli/entry_command.rb +728 -0
  27. data/lib/s7/s7cli/option.rb +101 -0
  28. data/lib/s7/secret_generator.rb +30 -0
  29. data/lib/s7/undo_stack.rb +7 -0
  30. data/lib/s7/unicode_data.rb +29 -0
  31. data/lib/s7/utils.rb +37 -0
  32. data/lib/s7/world.rb +150 -0
  33. data/setup.rb +1585 -0
  34. data/test/s7/attribute_test.rb +45 -0
  35. data/test/s7/gpass_file_test.rb +169 -0
  36. data/test/s7/gpass_file_test/passwords.gps.empty +1 -0
  37. data/test/s7/gpass_file_test/passwords.gps.one_entry +2 -0
  38. data/test/s7/gpass_file_test/passwords.gps.three_entries +3 -0
  39. data/test/s7/gpass_file_test/passwords.gps.with_folders +0 -0
  40. data/test/s7/secret_generator_test.rb +29 -0
  41. data/test/s7/unicode_data_test.rb +28 -0
  42. data/test/s7/world_test.rb +35 -0
  43. data/test/test_helper.rb +19 -0
  44. metadata +108 -0
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/ruby1.9
2
+ # -*- coding: utf-8 -*-
3
+
4
+ # Ruby 1.9 で Ruby-GetText-Package を使用するのはまだ時間がかかるようだ。
5
+ # そのため、LANG=C にして様子を見る。
6
+ ENV["LANG"] = "C"
7
+
8
+ $:.unshift(File.expand_path("../lib", File.dirname(__FILE__)))
9
+
10
+ require "gettext"
11
+
12
+ require "s7"
13
+ require "s7/s7cli"
14
+
15
+ path = File.expand_path("../data/locale/", File.dirname(__FILE__))
16
+ GetText.bindtextdomain("s7", :path => path)
17
+ begin
18
+ S7::S7Cli.run(ARGV)
19
+ rescue S7::ApplicationError => e
20
+ puts(e.message)
21
+ puts("----- back trace -----")
22
+ raise e
23
+ end
24
+
25
+ # Local Variables:
26
+ # mode: ruby
27
+ # End:
@@ -0,0 +1,28 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # gettext のモック
4
+ module GetText
5
+ def self.included(mod)
6
+ class << mod
7
+ def _(s)
8
+ return s
9
+ end
10
+
11
+ def N_(s)
12
+ return s
13
+ end
14
+ end
15
+ end
16
+
17
+ def _(s)
18
+ return s
19
+ end
20
+
21
+ def N_(s)
22
+ return s
23
+ end
24
+
25
+ def bindtextdomain(*args)
26
+ end
27
+ module_function :bindtextdomain
28
+ end
@@ -0,0 +1,12 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # S7 の名前空間を定義。
4
+ module S7
5
+ # バージョン。
6
+ VERSION = "0.0.1"
7
+ end
8
+
9
+ require "s7/world"
10
+ require "s7/s7_file"
11
+ require "s7/exception"
12
+ require "s7/gpass_file"
@@ -0,0 +1,7 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module S7
4
+ # 操作を表現する。
5
+ class Action
6
+ end
7
+ end
@@ -0,0 +1,226 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require "date"
4
+ require "gettext"
5
+
6
+ module S7
7
+ # 属性を表現する。
8
+ class Attribute
9
+ include GetText
10
+
11
+ # サポートしている属性のクラス。
12
+ @@attribute_classes = {}
13
+
14
+ class << self
15
+ def create_instance(type, options)
16
+ return @@attribute_classes[type].new(options)
17
+ end
18
+
19
+ # 属性の型名の配列を返す。
20
+ def types
21
+ return @@attribute_classes.keys
22
+ end
23
+
24
+ private
25
+
26
+ def type(name)
27
+ @@attribute_classes[name] = self
28
+ self.const_set("TYPE", name)
29
+ end
30
+ end
31
+
32
+ # 名前。
33
+ attr_accessor :name
34
+
35
+ # 機密情報かどうか。true であれば機密情報、false であればそうでない。
36
+ attr_accessor :secret
37
+
38
+ # 値を編集できるかどうか。true であれば編集でき、false であれ
39
+ # ばそうでない。
40
+ attr_accessor :editabled
41
+
42
+ # 削除できるかどうか。true であれば削除できず、false であれ
43
+ # ばそうでない。
44
+ attr_accessor :protected
45
+
46
+ def initialize(options)
47
+ self.name = options["name"]
48
+ self.value = options["value"]
49
+ self.secret = options["secret"] ? true : false
50
+ if options.key?("editabled")
51
+ self.editabled = options["editabled"] ? true : false
52
+ else
53
+ self.editabled = true
54
+ end
55
+ self.protected = options["protected"] ? true : false
56
+ end
57
+
58
+ # value を取得する。
59
+ def value
60
+ if @value.nil?
61
+ return nil
62
+ else
63
+ return get_value
64
+ end
65
+ end
66
+
67
+ # value を設定する。
68
+ def value=(val)
69
+ if val.nil?
70
+ @value = val
71
+ else
72
+ set_value(val)
73
+ end
74
+ end
75
+
76
+ # 属性の型を取得する。
77
+ def type
78
+ return self.class.const_get("TYPE")
79
+ end
80
+
81
+ # 機密情報かどうかを取得する。
82
+ # 機密情報の場合、true を返す。そうでなれば false を返す。
83
+ def secret?
84
+ return secret ? true : false
85
+ end
86
+
87
+ # ユーザによる値の編集ができるかどうかを取得する。
88
+ # 編集できる場合、true を返す。そうでなければ true を返す。
89
+ def editable?
90
+ return editabled ? true : false
91
+ end
92
+
93
+ # ユーザによる削除ができるかどうかを取得する。
94
+ # 削除できる場合、true を返す。そうでなければ true を返す。
95
+ def protected?
96
+ return protected ? true : false
97
+ end
98
+
99
+ # value を表示するために文字列に変換する。
100
+ # このとき、 secret が true であれば「*」でマスクする。
101
+ def display_value(secret = @secret)
102
+ if secret
103
+ return "*" * value.to_s.length
104
+ else
105
+ return value.to_s
106
+ end
107
+ end
108
+
109
+ private
110
+
111
+ def get_value
112
+ return @value
113
+ end
114
+
115
+ def set_value(val)
116
+ @value = val
117
+ end
118
+ end
119
+
120
+ # 文字列の属性を表現する。
121
+ class TextAttribute < Attribute
122
+ type("text")
123
+
124
+ private
125
+
126
+ def get_value
127
+ return @value.to_s.force_encoding("utf-8")
128
+ end
129
+
130
+ def set_value(val)
131
+ @value = val.to_s.force_encoding("utf-8")
132
+ end
133
+ end
134
+
135
+ # 数値の属性を表現する。
136
+ class NumericAttribute < Attribute
137
+ type("numeric")
138
+
139
+ private
140
+
141
+ def get_value
142
+ return @value.to_i
143
+ end
144
+
145
+ def set_value(val)
146
+ @value = val.to_i
147
+ end
148
+ end
149
+
150
+ # 真偽値の属性を表現する。
151
+ class BooleanAttribute < Attribute
152
+ type("boolean")
153
+
154
+ # value を表示するために文字列に変換する。
155
+ # secret が true であれば「*」を返す。
156
+ # そうでなければ、Yes か No を返す。
157
+ def display_value(secret = @secret)
158
+ if secret
159
+ return "*"
160
+ else
161
+ return value ? _("Yes") : _("No")
162
+ end
163
+ end
164
+
165
+ private
166
+
167
+ def get_value
168
+ return @value ? true : false
169
+ end
170
+
171
+ def set_value(val)
172
+ @value = val ? true : false
173
+ end
174
+ end
175
+
176
+ # 日時の属性を表現する。
177
+ class DateTimeAttribute < Attribute
178
+ type("datetime")
179
+
180
+ # value を表示するために文字列に変換する。
181
+ # secret が true であれば「*」を返す。
182
+ # そうでなければ、「%Y/%m/%d %H:%M:%S」でフォーマットした文字列を返す。
183
+ # また、時分秒が全て0の場合は「%Y/%m/%d」でフォーマットする。
184
+ def display_value(secret = @secret)
185
+ if secret
186
+ return "*"
187
+ else
188
+ format = "%Y/%m/%d"
189
+ if value.hour != 0 || value.min != 0 || value.sec != 0
190
+ format << " %H:%M:%S"
191
+ end
192
+ return value.strftime(format)
193
+ end
194
+ end
195
+
196
+ private
197
+
198
+ def get_value
199
+ return @value.to_datetime
200
+ end
201
+
202
+ def set_value(val)
203
+ case val
204
+ when Time, DateTime, Date
205
+ @value = val.to_datetime
206
+ else
207
+ @value = DateTime.parse(val.to_s)
208
+ end
209
+ end
210
+ end
211
+
212
+ # ファイルの属性を表現する。
213
+ class FileAttribute < Attribute
214
+ type("file")
215
+ end
216
+
217
+ # 画像の属性を表現する。
218
+ class FigureAttribute < FileAttribute
219
+ type("figure")
220
+ end
221
+
222
+ # 不明な属性を表現する。
223
+ class UnknownAttribute < Attribute
224
+ type("unknown")
225
+ end
226
+ end
@@ -0,0 +1,110 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require "openssl"
4
+
5
+ module S7
6
+ # 秘密鍵暗号化方式を用いた暗号化処理を表現する。
7
+ class Cipher
8
+ @@cipher_classes = {}
9
+
10
+ class << self
11
+ def create_instance(type, options)
12
+ return @@cipher_classes[type].new(options)
13
+ end
14
+
15
+ private
16
+
17
+ def cipher_type(name)
18
+ if @@cipher_classes.nil?
19
+ @@cipher_classes = {}
20
+ end
21
+ @@cipher_classes[name] = self
22
+ self.const_set("CIPHER_TYPE", name)
23
+ end
24
+ end
25
+
26
+ attr_accessor :options
27
+
28
+ def initialize(options)
29
+ self.options = options
30
+ end
31
+
32
+ # io で指定した IO からデータを読み込み、復号する。
33
+ def decrypt(io)
34
+ begin
35
+ cipher = create_cipher
36
+ cipher.decrypt
37
+ parse_options(cipher, options)
38
+ s = ""
39
+ while d = io.read(cipher.block_size)
40
+ s << cipher.update(d)
41
+ end
42
+ s << cipher.final
43
+ rescue OpenSSL::Cipher::CipherError
44
+ raise InvalidPassphrase
45
+ end
46
+ return s
47
+ end
48
+
49
+ # io で指定した IO からデータを読み込み、暗号化する。
50
+ def encrypt(io)
51
+ cipher = create_cipher
52
+ cipher.encrypt
53
+ parse_options(cipher, options)
54
+ s = ""
55
+ while d = io.read(cipher.block_size)
56
+ s << cipher.update(d)
57
+ end
58
+ s << cipher.final
59
+ return s
60
+ end
61
+
62
+ private
63
+
64
+ def create_cipher
65
+ cipher_type = self.class.const_get("CIPHER_TYPE")
66
+ return OpenSSL::Cipher::Cipher.new(cipher_type)
67
+ end
68
+
69
+ def parse_options(cipher, options)
70
+ if options.key?(:passphrase)
71
+ cipher.pkcs5_keyivgen(options[:passphrase])
72
+ elsif options.key?(:key)
73
+ cipher.key_len = options[:key].length
74
+ cipher.key = options[:key].key
75
+ if options.key?(:iv)
76
+ cipher.iv = options[:iv]
77
+ end
78
+ else
79
+ raise ArgumentError, "too few options: :passphrase or :key"
80
+ end
81
+ if options.key?(:padding)
82
+ cipher.padding = options[:padding]
83
+ end
84
+ end
85
+ end
86
+
87
+ # 秘密鍵方式の一つ AES を用いて暗号化処理を行うクラスを表現する。
88
+ class Aes256CbcCipher < Cipher
89
+ cipher_type "AES-256-CBC"
90
+ end
91
+
92
+ # 秘密鍵方式の一つ Blowfish を用いて暗号化処理を行うクラスを表現する。
93
+ class BfCbcCipher < Cipher
94
+ cipher_type "BF-CBC"
95
+ end
96
+
97
+ # Cipher クラスと同じインタフェースを持つが、暗号化しないクラスを表現
98
+ # する。
99
+ class PlainCipher < Cipher
100
+ cipher_type "plain"
101
+
102
+ def encrypt(io)
103
+ return io.read
104
+ end
105
+
106
+ def decrypt(io)
107
+ return io.read
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,41 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require "fileutils"
4
+
5
+ module S7
6
+ # 設定を表現する。
7
+ class Configuration
8
+ # デフォルトの秘密鍵暗号方式。
9
+ DEFAULT_CIPHER_TYPE = "AES-256-CBC"
10
+
11
+ # World オブジェクト。
12
+ attr_accessor :world
13
+
14
+ # 秘密鍵暗号方式。
15
+ attr_accessor :cipher_type
16
+
17
+ def initialize(world)
18
+ @world = world
19
+ @cipher_type = DEFAULT_CIPHER_TYPE
20
+ end
21
+
22
+ # 設定をファイルに書き出す。
23
+ def save(path)
24
+ hash = {
25
+ "cipher_type" => @cipher_type,
26
+ }
27
+ FileUtils.touch(path)
28
+ File.open(path, "wb") do |f|
29
+ f.write(hash.to_yaml)
30
+ end
31
+ end
32
+
33
+ # 設定をファイルから読み込む。
34
+ def load(path)
35
+ File.open(path, "rb") do |f|
36
+ hash = YAML.load(f.read)
37
+ @cipher_type = hash["cipher_type"]
38
+ end
39
+ end
40
+ end
41
+ end