keystorage 0.5.1 → 0.5.7

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
  SHA1:
3
- metadata.gz: ad8f4fbc6eb42851fd6be0c507430a1715894da4
4
- data.tar.gz: 31cd005dbc8e0c2c813d91e6d23b730911115c43
3
+ metadata.gz: 5772937588dc3df5bec1a71d4decdb377c44cc5d
4
+ data.tar.gz: cea3aa650a0c1e8ff6737b5c89a24efd19c3d926
5
5
  SHA512:
6
- metadata.gz: 2af20459da3de9df711bd72f021ff74c011fed2a749903b85f2a35ff501a17b78a0e6f3ce0a2e8ad86ae42815bbc757843e7448cef06158f9de85256920eeb12
7
- data.tar.gz: f46d937aa796ba6cf144e9127918d66c62b217fb7ab338d049e08fa0830c55a3d40bf9862d29fa53215b4631281308cf8074e2ad6a758e347c92d7236ecdb24e
6
+ metadata.gz: 3c94373cfc511b914ed78315639242b650bd79158d2f0c7dff814f8490ad1e555b7c280f30fd9e5175d9c8336be2d9a8343fe07a91c6bc16344bdaaa2f58bcfe
7
+ data.tar.gz: bf1b0665cd890f17fb6c3c0294224861038f942ee1a5b60f585c1fd93d976fe2d394b07b22346ce79ce15437f29d9197313f0f81fc16ab6c7e119892872dd1d3
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.0
6
+ - 2.2.0
7
+ addons:
8
+ code_climate:
9
+ repo_token: 7e1de01d60bd2dd9dac1bf49ab3e62b631f1299dde4c0f4595f277ae01c1e9f4
data/Gemfile CHANGED
@@ -1,9 +1,5 @@
1
1
  source "http://rubygems.org"
2
2
  gemspec
3
3
 
4
- # Add dependencies required to use your gem here.
5
- # Example:
6
- # gem "activesupport", ">= 2.3.5"
7
-
8
- # Add dependencies to develop your gem here.
9
- # Include everything needed to run rake, tests, features, etc.
4
+ gem "simplecov", :require=>false, group: :test
5
+ gem "codeclimate-test-reporter", group: :test
data/README.md CHANGED
@@ -1,6 +1,11 @@
1
1
  keystorage
2
2
  ----------
3
3
 
4
+ [![Gem Version](https://badge.fury.io/rb/keystorage.svg)](http://badge.fury.io/rb/keystorage)
5
+ [![Build Status](https://travis-ci.org/tumf/keystorage.svg?branch=master)](https://travis-ci.org/tumf/keystorage)
6
+ [![Code Climate](https://codeclimate.com/github/tumf/keystorage/badges/gpa.svg)](https://codeclimate.com/github/tumf/keystorage)
7
+ [![Test Coverage](https://codeclimate.com/github/tumf/keystorage/badges/coverage.svg)](https://codeclimate.com/github/tumf/keystorage)
8
+
4
9
  Simple password storage.
5
10
 
6
11
  ## Install
@@ -12,12 +17,14 @@ Simple password storage.
12
17
 
13
18
  -> % keystorage
14
19
  Commands:
20
+ keystorage exec # execute child process with set envvars
15
21
  keystorage get # Get a encrypted value of the key of the group
16
22
  keystorage groups # List groups
17
23
  keystorage help [COMMAND] # Describe available commands or one specific command
18
24
  keystorage keys # List keys of the group
19
25
  keystorage password # Update storage secret
20
26
  keystorage set # Set a value of the key of the group
27
+ keystorage version # show version info
21
28
 
22
29
  Options:
23
30
  -v, [--verbose], [--no-verbose]
data/Rakefile CHANGED
@@ -4,4 +4,4 @@ Rake::VersionTask.new
4
4
  require 'rspec/core/rake_task'
5
5
  RSpec::Core::RakeTask.new(:spec)
6
6
 
7
- task :default => :test
7
+ task :default => [:spec]
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.1
1
+ 0.5.7
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
  $:.unshift(File.join(File.dirname(__FILE__),'..','lib'))
3
+ require 'bundler/setup'
3
4
  require 'keystorage/cli'
4
5
  Keystorage::CLI.start(ARGV)
@@ -27,8 +27,9 @@ Gem::Specification.new do |s|
27
27
  s.summary = "Simple password storage"
28
28
 
29
29
  s.add_dependency('thor')
30
-
30
+ s.add_dependency('version')
31
+
31
32
  s.add_development_dependency('rake')
32
33
  s.add_development_dependency('rspec')
33
- s.add_development_dependency('version')
34
+ s.add_development_dependency('fakefs')
34
35
  end
@@ -15,62 +15,6 @@ module Keystorage
15
15
  class NoSecret < StandardError; end
16
16
  class FormatNotSupport < StandardError; end
17
17
 
18
- def sign message,secret=secret
19
- raise NoSecret.new("set env KEYSTORAGE_SECRET") unless secret
20
- OpenSSL::HMAC.hexdigest('sha512',secret, message)
21
- end
22
-
23
- def token
24
- SecureRandom.urlsafe_base64(nil, false)
25
- end
26
-
27
- def root
28
- raise NoRootGroup unless file.has_key?("@")
29
- file["@"] || {}
30
- end
31
-
32
- def root! secret=secret,data=file
33
- data["@"] = {}
34
- data["@"]["token"] = token
35
- data["@"]["sig"] = sign(data["@"]["token"],secret)
36
- data
37
- end
38
-
39
- # file validation
40
- def valid?
41
- sign(root["token"]) == root["sig"]
42
- rescue NoRootGroup
43
- write root!
44
- end
45
-
46
- def encode(str,secret=secret)
47
- enc = OpenSSL::Cipher::Cipher.new('aes256')
48
- enc.encrypt.pkcs5_keyivgen(secret)
49
- ((enc.update(str) + enc.final).unpack("H*")).first.to_s
50
- end
51
-
52
- def decode(str,secret=secret)
53
- dec = OpenSSL::Cipher::Cipher.new('aes256')
54
- dec.decrypt.pkcs5_keyivgen(secret)
55
- (dec.update(Array.new([str]).pack("H*")) + dec.final)
56
- end
57
-
58
- def path
59
- options[:file] || ENV['KEYSTORAGE_FILE'] || DEFAULT_FILE
60
- end
61
-
62
- def file
63
- YAML.load(File.new(path)) || {}
64
- end
65
-
66
- def write data
67
- File.open(path,'w',0600) { |f| YAML.dump(data,f) }
68
- end
69
-
70
- def secret
71
- options[:secret] || ENV['KEYSTORAGE_SECRET'] || DEFAULT_SECRET
72
- end
73
-
74
18
  def render out,format =:text
75
19
  case format
76
20
  when :text then
@@ -3,6 +3,7 @@ require 'keystorage'
3
3
  require 'keystorage/manager'
4
4
  require 'thor'
5
5
  require 'optparse'
6
+ require 'version'
6
7
 
7
8
  module Keystorage
8
9
  class CLI < Thor
@@ -12,22 +13,22 @@ module Keystorage
12
13
  def start(given_args = ARGV, config = {})
13
14
  # parse global options: Thor is not support global-options.
14
15
  # Like: command global-options subcommand options
15
- global_options = []
16
+ new_global_options = []
16
17
  OptionParser.new do |opt|
17
18
  @global_options.each { |name,config|
18
19
  case config[:type]
19
20
  when :boolean then
20
- opt.on(config[:aliases],"--#{name.to_s}") { |v| global_options << "--#{name.to_s}"}
21
- opt.on(config[:aliases],"--no-#{name.to_s}") { |v| global_options << "--no-#{name.to_s}"}
21
+ opt.on(config[:aliases],"--#{name.to_s}") { |v| new_global_options << "--#{name.to_s}"}
22
22
  when :string then
23
- opt.on(config[:aliases],"--#{name.to_s}=VALUE") { |v| global_options << "--#{name.to_s}=#{v}"}
23
+ opt.on(config[:aliases],"--#{name.to_s}=VALUE") { |v| new_global_options << "--#{name.to_s}=#{v}"}
24
24
  end
25
25
  }
26
26
  opt.parse!(given_args)
27
27
  end
28
- given_args+=global_options
28
+ given_args+=new_global_options
29
29
  super(given_args,config)
30
30
  end
31
+ attr_reader :global_options
31
32
 
32
33
  def global_option *params
33
34
  @global_options ||= {}
@@ -68,5 +69,16 @@ module Keystorage
68
69
  Manager.new(options).password(new_secret)
69
70
  end
70
71
 
72
+ desc "exec","execute child process with set envvars"
73
+ def exec *command
74
+ #@todo: ask if new_secret == nil
75
+ Manager.new(options).exec(command)
76
+ end
77
+
78
+ desc "version","show version info"
79
+ def version
80
+ puts Version.current
81
+ end
82
+
71
83
  end
72
84
  end
@@ -56,5 +56,79 @@ module Keystorage
56
56
  retry
57
57
  end
58
58
 
59
+ def exec *cmd
60
+ raise SecretMissMatch unless valid?
61
+ system(envs.collect{ |k,v| "#{k}='#{v}'" }.join(' ') + " " + cmd.join(' '))
62
+ end
63
+
64
+ private
65
+
66
+ def envs
67
+ result = {}
68
+ groups.each { |g|
69
+ keys(g).each { |k|
70
+ result["#{g}_#{k}"] = get(g,k)
71
+ }
72
+ }
73
+ result
74
+ end
75
+
76
+ def sign message,_secret=secret
77
+ raise NoSecret.new("set env KEYSTORAGE_SECRET") unless _secret
78
+ OpenSSL::HMAC.hexdigest('sha512',_secret, message)
79
+ end
80
+
81
+ def token
82
+ SecureRandom.urlsafe_base64(nil, false)
83
+ end
84
+
85
+ def root
86
+ raise NoRootGroup unless file.has_key?("@")
87
+ file["@"] || {}
88
+ end
89
+
90
+ def root! _secret=secret,data=file
91
+ data["@"] = {}
92
+ data["@"]["token"] = token
93
+ data["@"]["sig"] = sign(data["@"]["token"],_secret)
94
+ data
95
+ end
96
+
97
+ # file validation
98
+ def valid?
99
+ sign(root["token"]) == root["sig"]
100
+ rescue NoRootGroup
101
+ write root! and true
102
+ end
103
+
104
+ def encode(str,_secret=secret)
105
+ enc = OpenSSL::Cipher::Cipher.new('aes256')
106
+ enc.encrypt.pkcs5_keyivgen(_secret)
107
+ ((enc.update(str) + enc.final).unpack("H*")).first.to_s
108
+ end
109
+
110
+ def decode(str,_secret=secret)
111
+ dec = OpenSSL::Cipher::Cipher.new('aes256')
112
+ dec.decrypt.pkcs5_keyivgen(_secret)
113
+ (dec.update(Array.new([str]).pack("H*")) + dec.final)
114
+ end
115
+
116
+ def path
117
+ options[:file] || ENV['KEYSTORAGE_FILE'] || DEFAULT_FILE
118
+ end
119
+
120
+ def file
121
+ YAML.load(File.new(path)) || {}
122
+ end
123
+
124
+ def write data
125
+ FileUtils.mkdir_p(File.dirname(path))
126
+ File.open(path,'w',0600) { |f| YAML.dump(data,f) }
127
+ end
128
+
129
+ def secret
130
+ options[:secret] || ENV['KEYSTORAGE_SECRET'] || DEFAULT_SECRET
131
+ end
132
+
59
133
  end
60
134
  end
@@ -1,7 +1,120 @@
1
+ # coding: utf-8
1
2
  require 'keystorage/cli'
3
+
2
4
  describe Keystorage::CLI do
3
- subject { Keystorage::CLI::new(['-f','test.yml']).options[:file] }
4
- it {
5
- is_expected.to be ''
6
- }
5
+ subject { Keystorage::CLI.start(argv) }
6
+
7
+ describe ".start" do
8
+ context "unknown global-options are specified" do
9
+ let(:argv) { ['--aaa=myfile','groups'] }
10
+ it "puts options back of subcommand" do
11
+ expect { subject }.to raise_error(OptionParser::InvalidOption)
12
+ end
13
+ end
14
+
15
+ context "string-type global-options are specified" do
16
+ let(:argv) { ['-f','myfile','groups'] }
17
+ it "puts options back of subcommand" do
18
+ expect(Thor).to receive(:start).with(['groups','--file=myfile'],{}).once
19
+ subject
20
+ end
21
+ end
22
+
23
+ context "boolean-type `-v` global-options are specified" do
24
+ let(:argv) { ['-v','groups'] }
25
+ it "puts options back of subcommand" do
26
+ expect(Thor).to receive(:start).with(['groups','--verbose'],{}).once
27
+ subject
28
+ end
29
+ end
30
+ context "boolean-type `--no-verbose` global-options are specified" do
31
+ let(:argv) { ['--no-verbose','groups'] }
32
+ it "puts options back of subcommand" do
33
+ expect { subject }.to raise_error(OptionParser::InvalidOption)
34
+ end
35
+ end
36
+ end
37
+
38
+ describe ".global_option" do
39
+ it "adds to @global_options and call `class_option`" do
40
+ expect(Keystorage::CLI).to receive(:class_option)
41
+ .with(:test, :aliases =>"-t", :type => :boolean).once
42
+ Keystorage::CLI.global_option(:test, :aliases =>"-t", :type => :boolean)
43
+ expect(Keystorage::CLI.global_options.has_key?(:test)).to be true
44
+ end
45
+ end
46
+
47
+ describe "#groups" do
48
+ let(:argv) { ['groups'] }
49
+ it "puts list of groups" do
50
+ allow(Keystorage::Manager).to receive_message_chain('new.groups')
51
+ .and_return( ["group1","group2","group3"] )
52
+ expect(STDOUT).to receive(:puts).with("group1\ngroup2\ngroup3").once
53
+ subject
54
+ end
55
+ end
56
+
57
+ describe "#keys" do
58
+ let(:argv) { ['keys','group1'] }
59
+ it "puts keys in the group" do
60
+ allow(Keystorage::Manager).to receive_message_chain('new.keys')
61
+ .and_return( ["key1","key2","key3"] )
62
+
63
+ expect(STDOUT).to receive(:puts).with("key1\nkey2\nkey3").once
64
+ subject
65
+ end
66
+ end
67
+
68
+ describe "#get" do
69
+ let(:argv) { ['get','group1','key1'] }
70
+ it "puts value of the key in the group" do
71
+ allow(Keystorage::Manager).to receive_message_chain('new.get')
72
+ .and_return( ["value"] )
73
+
74
+ expect(STDOUT).to receive(:puts).with("value").once
75
+ subject
76
+ end
77
+ end
78
+
79
+
80
+ describe "#set" do
81
+ let(:argv) { ['set','group1','key1','vaule'] }
82
+ it "sets value of the key in the group" do
83
+ allow(Keystorage::Manager).to receive_message_chain('new.set')
84
+ .and_return("value")
85
+
86
+ expect(STDOUT).to receive(:puts).with("value").once
87
+ subject
88
+ end
89
+ end
90
+
91
+ describe "#password" do
92
+ let(:argv) { ['password','p@ssw0rd'] }
93
+ it "updates secret of all keys in the file" do
94
+ expect(Keystorage::Manager).to receive_message_chain('new.password')
95
+ .with('p@ssw0rd')
96
+ subject
97
+ end
98
+ end
99
+
100
+ describe "#exec" do
101
+ let(:argv) { ['exec','mycommand','arg1','arg2'] }
102
+ it "updates secret of all keys in the file" do
103
+ expect(Keystorage::Manager).to receive_message_chain('new.exec')
104
+ .with(['mycommand','arg1','arg2'])
105
+ subject
106
+ end
107
+ end
108
+
109
+ describe "#version" do
110
+ let(:argv) { ['version'] }
111
+ let(:ver) {
112
+ File.read(File.join(File.dirname(__FILE__),'..','..','VERSION')).chomp
113
+ }
114
+ it "shows version" do
115
+ expect(STDOUT).to receive(:puts).with(ver).once
116
+ subject
117
+ end
118
+ end
119
+
7
120
  end
@@ -0,0 +1,3 @@
1
+ ---
2
+ "@":
3
+ sig: "abc"
@@ -1,13 +1,383 @@
1
1
  require 'keystorage/manager'
2
+
3
+ def yaml name
4
+ File.join(File.dirname(__FILE__),'files',"#{name}.yml")
5
+ end
6
+
2
7
  describe Keystorage::Manager do
3
- before {
4
- @ks = Keystorage::Manager.new
5
- }
6
- subject { @ks.get("mygroup","key") }
7
- it {
8
- is_expected.to be ""
8
+ let(:files){
9
+ {
10
+ "1"=>{"@"=>{"sig"=>"abc"}},
11
+ "2"=>{"@"=>{"sig"=>"abc","token"=>"def"},"g1"=>{ "k1" => "abcdefg", "k2" =>"" },"g2"=>{}},
12
+ }
9
13
  }
14
+ before { @manager = Keystorage::Manager.new }
15
+
16
+ # public methods
17
+ describe "#groups" do
18
+ subject { @manager.groups }
19
+ it "returns array of groups" do
20
+ allow(@manager).to receive(:file)
21
+ .and_return(files["2"])
22
+ is_expected.to eq ["g1","g2"]
23
+ end
24
+ end
25
+
26
+ describe "#keys" do
27
+ subject { @manager.keys("g1") }
28
+ it "returns array of keys" do
29
+ allow(@manager).to receive(:file)
30
+ .and_return(files["2"])
31
+
32
+ is_expected.to eq ["k1","k2"]
33
+ end
34
+ end
35
+
36
+ describe "#get" do
37
+ subject { @manager.get("g1","k1") }
38
+ before {
39
+ allow(@manager).to receive(:file)
40
+ .and_return(files["2"])
41
+ }
42
+ context "has valid secret" do
43
+ before {
44
+ allow(@manager).to receive(:valid?)
45
+ .and_return(true)
46
+ }
47
+ it "returns value of the key in the group" do
48
+ expect(@manager).to receive(:decode).with("abcdefg").once
49
+ subject
50
+ end
51
+ end
52
+ context "has no valid secret" do
53
+ before {
54
+ allow(@manager).to receive(:valid?)
55
+ .and_return(false) }
56
+ it "raise Keystorage::SecretMissMatch" do
57
+ expect { subject }.to raise_error(Keystorage::SecretMissMatch)
58
+ end
59
+
60
+ end
61
+ end
62
+
63
+ describe "#set" do
64
+ before {
65
+ allow(@manager).to receive(:file)
66
+ .and_return(files["2"])
67
+ }
68
+
69
+ context "group name '@'" do
70
+ subject { @manager.set("@","k1","v1") }
71
+ it "raise Keystorage::RejectGroupName" do
72
+ expect { subject }.to raise_error(Keystorage::RejectGroupName)
73
+ end
74
+ end
75
+
76
+ context "has valid secret" do
77
+ subject { @manager.set("g1","k1","v1") }
78
+ before {
79
+ allow(@manager).to receive(:valid?)
80
+ .and_return(true)
81
+ }
82
+ it "sets the value to the key in the group" do
83
+ FakeFS do
84
+ subject
85
+ expect(@manager.get('g1','k1')).to eq "v1"
86
+ end
87
+ end
88
+ end
89
+
90
+ context "has no valid secret" do
91
+ subject { @manager.set("g1","k1","v1") }
92
+ before {
93
+ allow(@manager).to receive(:valid?)
94
+ .and_return(false)
95
+ }
96
+ it "raise Keystorage::SecretMissMatch" do
97
+ expect { subject }.to raise_error(Keystorage::SecretMissMatch)
98
+ end
99
+
100
+ end
101
+ end
102
+
103
+ describe "#password" do
104
+ let(:new_password) { "zxcvbnm" }
105
+ subject { @manager.password(new_password) }
106
+
107
+ context "file not found" do
108
+ before {
109
+ @manager = Keystorage::Manager.new( {:file=>"hoge",:secret=>"fuga"})
110
+ }
111
+ it "creates new keystorage file" do
112
+ FakeFS do
113
+ subject
114
+ expect(File.exists?("hoge")).to eq true
115
+ expect(@manager.send(:file).has_key?("@")).to eq true
116
+ end
117
+ end
118
+ end
119
+
120
+ context "has valid secret" do
121
+
122
+ before {
123
+ @manager = Keystorage::Manager.new( {:file=>"hoge",:secret=>"fuga"})
124
+ }
125
+ it "updates password to `new_password`" do
126
+ FakeFS do
127
+ @manager.set("a","b","c")
128
+ subject
129
+ expect { @manager.get("a","b") }.to raise_error(Keystorage::SecretMissMatch)
130
+ @manager = Keystorage::Manager.new( {:file=>"hoge",:secret=>new_password})
131
+ expect(@manager.get("a","b")).to eq "c"
132
+ end
133
+ end
134
+ end
135
+
136
+ context "has no valid secret" do
137
+ before {
138
+ allow(@manager).to receive(:valid?)
139
+ .and_return(false)
140
+ }
141
+ it "raise Keystorage::SecretMissMatch" do
142
+ expect { subject }.to raise_error(Keystorage::SecretMissMatch)
143
+ end
144
+
145
+ end
146
+ end
147
+
148
+ describe "#exec" do
149
+ let(:cmd) { ["ls","-a b"] }
150
+ subject { @manager.exec(cmd) }
151
+
152
+ context "has valid secret" do
153
+ before {
154
+ @manager = Keystorage::Manager.new( {:file=>"hoge",:secret=>"fuga"} )
155
+ allow(@manager).to receive(:valid?)
156
+ .and_return(true)
157
+ }
158
+ it "execute command with env-vars" do
159
+ FakeFS do
160
+ @manager.set("a","b","c")
161
+ @manager.set("a","b","d e f")
162
+ @manager.set("x","y","z")
163
+
164
+ expect(@manager).to receive(:system)
165
+ .with("a_b='d e f' x_y='z' ls -a b")
166
+ .and_return(true)
167
+ subject
168
+ end
169
+ end
170
+ end
171
+
172
+ context "has no valid secret" do
173
+ before {
174
+ allow(@manager).to receive(:valid?)
175
+ .and_return(false)
176
+ }
177
+ it "raise Keystorage::SecretMissMatch" do
178
+ expect { subject }.to raise_error(Keystorage::SecretMissMatch)
179
+ end
180
+
181
+ end
182
+ end
183
+
184
+
185
+ # private methods
186
+ describe "#sign" do
187
+ context "secret is nil" do
188
+ it "raise NoSecret" do
189
+ expect { @manager.send(:sign,"text",nil) }
190
+ .to raise_error(Keystorage::NoSecret)
191
+ end
192
+
193
+ end
194
+ context "secret is not nil" do
195
+ subject { @manager.send(:sign,"text","p@ssw0rd") }
196
+ it "returns sign" do
197
+ allow(OpenSSL::HMAC).to receive(:hexdigest)
198
+ .and_return("sample-sig")
199
+
200
+ is_expected.to eq "sample-sig"
201
+ end
202
+
203
+ end
204
+ end
205
+
206
+ describe "#token" do
207
+ subject { @manager.send(:token) }
208
+
209
+ it "returns token" do
210
+ allow(SecureRandom).to receive(:urlsafe_base64)
211
+ .and_return("sample-token")
212
+ is_expected.to eq "sample-token"
213
+ end
214
+
215
+ end
216
+
217
+ describe "#root" do
218
+ context "file has '@' key" do
219
+ let(:root) { {"test1"=>"test2"} }
220
+ let(:data) { { "@" => root,"group1" => {"key1"=>"value1"} } }
221
+ subject { @manager.send(:root) }
222
+
223
+ it "returns Hash of root" do
224
+ allow(@manager).to receive(:file)
225
+ .and_return(data)
226
+ is_expected.to eq root
227
+ end
228
+ end
229
+ context "file has no '@' key" do
230
+ let(:data) { { "group1" => {"key1"=>"value1"} } }
231
+ it "raise NoRootGroup" do
232
+ allow(@manager).to receive(:file)
233
+ .and_return(data)
234
+
235
+ expect { @manager.send(:root) }
236
+ .to raise_error(Keystorage::NoRootGroup)
237
+ end
238
+
239
+ end
240
+ end
241
+
242
+ describe "#valid?" do
243
+ context "file has no root" do
244
+ subject { @manager.send(:valid?) }
245
+ let(:data) { { "group1" => {"key1"=>"value1"} } }
246
+ it "writes root and return true" do
247
+ allow(@manager).to receive(:file)
248
+ .and_return(data)
249
+ allow(@manager).to receive(:write)
250
+ .and_return(true)
251
+ expect(@manager).to receive(:write)
252
+ is_expected.to eq true
253
+ end
254
+ end
255
+ end
256
+
257
+ describe "#encode" do
258
+ let(:str) { "test message" }
259
+ let(:secret) { "s3cr3t" }
260
+ subject { @manager.send(:encode,str,secret) }
261
+ it "returns encoded string" do
262
+ is_expected.to eq "a191a5111cfee36a94bba4dc0a17c31d"
263
+ end
264
+ end
265
+
266
+ describe "#decode" do
267
+ let(:str) { "test message" }
268
+ let(:encoded) { "a191a5111cfee36a94bba4dc0a17c31d" }
269
+ let(:secret) { "s3cr3t" }
270
+ subject { @manager.send(:decode,encoded,secret) }
271
+ it "returns decoded string" do
272
+ is_expected.to eq str
273
+ end
274
+ end
275
+
276
+ describe "#file" do
277
+ subject { @manager.send(:file) }
278
+ it "returns data from path" do
279
+ allow(@manager).to receive(:path)
280
+ .and_return(yaml("1"))
281
+ is_expected.to eq files["1"]
282
+ end
283
+ end
284
+
285
+ describe "#write" do
286
+ let(:data) { { :test => "rspec"} }
287
+ subject { @manager.send(:write,data) }
288
+ it "writes data to file" do
289
+ FakeFS do
290
+ expect { subject }.not_to raise_error
291
+ expect(@manager.send(:file).has_key?(:test)).to eq true
292
+ end
293
+ end
294
+ end
295
+
296
+ describe "#path" do
297
+ subject { @manager.send(:path) }
298
+ let(:file_path) { "abcdefgh" }
299
+
300
+ context "options[:path] is set" do
301
+ before{
302
+ allow(@manager).to receive(:options)
303
+ .and_return({:file =>file_path})
304
+ }
305
+
306
+ it "returns options[:path]" do
307
+ is_expected.to eq file_path
308
+ end
309
+ end
310
+ context "options[:path] is not set" do
311
+ before {
312
+ allow(@manager).to receive(:options)
313
+ .and_return({})
314
+ }
315
+
316
+ context "ENV KEYSTORAGE_FILE is set" do
317
+ before{
318
+ allow(ENV).to receive(:[])
319
+ .with('KEYSTORAGE_FILE')
320
+ .and_return(file_path)
321
+ }
322
+ it "returns KEYSTORAGE_FILE" do
323
+ is_expected.to eq file_path
324
+ end
325
+ end
326
+
327
+ context "ENV KEYSTORAGE_FILE is not set" do
328
+ before{
329
+ allow(ENV).to receive(:[])
330
+ .with('KEYSTORAGE_FILE')
331
+ .and_return(nil)
332
+ }
333
+ it "returns DEFAULT_FILE" do
334
+ is_expected.to eq Keystorage::DEFAULT_FILE
335
+ end
336
+ end
337
+ end
338
+
339
+ end
340
+
341
+ describe "#secret" do
342
+ subject { @manager.send(:secret) }
343
+ let(:password) { "abcedfg" }
344
+
345
+ context "options[:secret] is set" do
346
+ it "returns options[:secret]" do
347
+ allow(@manager).to receive(:options)
348
+ .and_return({:secret =>password})
349
+ is_expected.to eq password
350
+ end
351
+ end
352
+ context "options[:secret] is not set" do
353
+ before {
354
+ allow(@manager).to receive(:options)
355
+ .and_return({})
356
+ }
357
+ context "ENV KEYSTORAGE_SECRET is set" do
358
+ before {
359
+ allow(ENV).to receive(:[])
360
+ .with('KEYSTORAGE_SECRET')
361
+ .and_return(password)
362
+ }
363
+
364
+ it "returns secret ENV[:secret]" do
365
+ is_expected.to eq password
366
+ end
367
+ end
368
+ context "ENV KEYSTORAGE_SECRET is not set" do
369
+ before {
370
+ allow(ENV).to receive(:[])
371
+ .with('KEYSTORAGE_SECRET')
372
+ .and_return(nil)
373
+ }
374
+ it "returns DEFAULT_SECRET" do
375
+ is_expected.to eq Keystorage::DEFAULT_SECRET
376
+ end
377
+ end
378
+ end
379
+
380
+ end
10
381
 
382
+ after { FakeFS::FileSystem.clear }
11
383
  end
12
- # ks = keystorage::Manager.new(:file =>"",:secret=> "P@ssword")
13
- # ks.get("mygroup","mykey") # => "mysecret"
@@ -0,0 +1,19 @@
1
+ # coding: utf-8
2
+ require 'keystorage'
3
+
4
+ describe Keystorage do
5
+ let(:test_class) { Struct.new(:a){ include Keystorage } }
6
+ subject { test_class.new }
7
+
8
+ describe "#render" do
9
+
10
+ context "Unknown format ':unknown' given" do
11
+ let(:format) { :unknown }
12
+ let(:string) { SecureRandom.urlsafe_base64(nil, false) }
13
+ it "raises Keystorage::FormatNotSupport" do
14
+ expect { subject.render(string,format) }.to raise_error(Keystorage::FormatNotSupport)
15
+ end
16
+ end
17
+
18
+ end
19
+ end
@@ -1,3 +1,12 @@
1
+ # coding: utf-8
2
+ require 'simplecov'
3
+ require "codeclimate-test-reporter"
4
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
5
+ SimpleCov::Formatter::HTMLFormatter,
6
+ CodeClimate::TestReporter::Formatter
7
+ ]
8
+ SimpleCov.start
9
+
1
10
  # This file was generated by the `rspec --init` command. Conventionally, all
2
11
  # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
12
  # The generated `.rspec` file contains `--require spec_helper` which will cause
@@ -89,3 +98,4 @@ RSpec.configure do |config|
89
98
  Kernel.srand config.seed
90
99
  =end
91
100
  end
101
+ require 'fakefs/spec_helpers'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: keystorage
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.5.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yoshihiro TAKAHARA
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: version
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rake
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -53,7 +67,7 @@ dependencies:
53
67
  - !ruby/object:Gem::Version
54
68
  version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
- name: version
70
+ name: fakefs
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
73
  - - ">="
@@ -76,6 +90,7 @@ extra_rdoc_files:
76
90
  files:
77
91
  - ".gitignore"
78
92
  - ".rspec"
93
+ - ".travis.yml"
79
94
  - Gemfile
80
95
  - LICENSE.txt
81
96
  - README.md
@@ -87,10 +102,10 @@ files:
87
102
  - lib/keystorage/cli.rb
88
103
  - lib/keystorage/manager.rb
89
104
  - spec/keystorage/cli_spec.rb
105
+ - spec/keystorage/files/1.yml
90
106
  - spec/keystorage/manager_spec.rb
107
+ - spec/keystorage_spec.rb
91
108
  - spec/spec_helper.rb
92
- - test/helper.rb
93
- - test/test_keystorage.rb
94
109
  homepage: http://github.com/tumf/keystorage
95
110
  licenses:
96
111
  - MIT
@@ -117,8 +132,8 @@ specification_version: 4
117
132
  summary: Simple password storage
118
133
  test_files:
119
134
  - spec/keystorage/cli_spec.rb
135
+ - spec/keystorage/files/1.yml
120
136
  - spec/keystorage/manager_spec.rb
137
+ - spec/keystorage_spec.rb
121
138
  - spec/spec_helper.rb
122
- - test/helper.rb
123
- - test/test_keystorage.rb
124
139
  has_rdoc:
@@ -1,18 +0,0 @@
1
- require 'rubygems'
2
- require 'bundler'
3
- begin
4
- Bundler.setup(:default, :development)
5
- rescue Bundler::BundlerError => e
6
- $stderr.puts e.message
7
- $stderr.puts "Run `bundle install` to install missing gems"
8
- exit e.status_code
9
- end
10
- require 'test/unit'
11
- require 'shoulda'
12
-
13
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
- $LOAD_PATH.unshift(File.dirname(__FILE__))
15
- require 'keystorage'
16
-
17
- class Test::Unit::TestCase
18
- end
@@ -1,36 +0,0 @@
1
- require 'helper'
2
- require 'fileutils'
3
-
4
- class TestKeystorage < Test::Unit::TestCase
5
- @@file = ".testkey"
6
- context "set / delete" do
7
- setup do
8
- Keystorage.set("abc","def","ghi",@@file)
9
- Keystorage.set("abc","123","456",@@file)
10
- end
11
- teardown do
12
- FileUtils.rm(@@file)
13
- end
14
-
15
- should "file exists" do
16
- assert File.exists?(@@file)
17
- end
18
-
19
- should "exist def and 123" do
20
- assert_equal "ghi",Keystorage.get("abc","def",@@file)
21
- assert_equal "456",Keystorage.get("abc","123",@@file)
22
- end
23
-
24
- should "delete only def" do
25
- Keystorage.delete("abc","def",@@file)
26
- assert_equal "456",Keystorage.get("abc","123",@@file)
27
- assert_equal false,Keystorage.get("abc","def",@@file)
28
- end
29
-
30
- should "delete abc group" do
31
- Keystorage.delete("abc",nil,@@file)
32
- assert_equal false,Keystorage.get("abc","123",@@file)
33
- assert_equal false,Keystorage.get("abc","def",@@file)
34
- end
35
- end
36
- end