keystorage 0.5.1 → 0.5.7

Sign up to get free protection for your applications and to get access to all the features.
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