pws 0.9.1 → 0.9.2

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.
data/README.md CHANGED
@@ -19,9 +19,20 @@ Originally based on [this tutorial](http://rbjl.net/41-tutorial-build-your-own-p
19
19
 
20
20
  Cucumber specs loosely based on [the ones](https://github.com/thecatwasnot/passwordsafe/blob/master/features/) by thecatwasnot - thanks
21
21
 
22
+ Features coming in 1.0
23
+ ---
24
+ Around March or April 2012
25
+
26
+ * Significantly improved crypto methods
27
+ * Tests for the crypto stuff
28
+ * Different storage format, but will be backwards compatible
29
+ * Little UI tweaks
30
+
22
31
  Contributions by
23
32
  ---
24
33
  * [brianewing](https://github.com/brianewing/)
34
+ * [dquimper](https://github.com/dquimper/)
35
+ * [grapz](https://github.com/grapz/)
25
36
 
26
37
  Copyright
27
38
  ---
data/Rakefile CHANGED
@@ -28,8 +28,10 @@ task :gemspec do
28
28
  gemspec.validate
29
29
  end
30
30
 
31
- require 'cucumber/rake/task'
32
- Cucumber::Rake::Task.new(:spec)
31
+ desc 'Run cucumber and rspec specs'
32
+ task :spec do
33
+ sh %[rspec spec] and sh %[cucumber features]
34
+ end
33
35
 
34
36
  task :default => :spec
35
37
  task :test => :spec
data/bin/pws CHANGED
@@ -1,89 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require_relative '../lib/pws'
4
-
5
- action_or_namespace = $*.shift
6
-
7
- if action_or_namespace =~ /^-.*$/
8
- @action = $*.shift
9
- @namespace = $& unless $& == ?-
10
- else
11
- @action = action_or_namespace
12
- @namespace = nil
13
- end
14
-
15
- @action = @action ? @action.to_sym : :show
16
- @args = [*$*]
17
-
18
- begin
19
- case @action
20
- when :v, :version
21
- puts "pws #{PWS::VERSION} by " + Paint["J-_-L", :bold] + " <https://github.com/janlelis/pws>"
22
- when :help, :actions, :commands
23
- puts \
24
- <<HELP
25
-
26
- #{Paint["Usage", :underline]}
27
-
28
- #{Paint['pws', :bold]} [-namespace] action [arguments]
29
-
30
- #{Paint["Info", :underline]}
31
-
32
- pws allows you to manage passwords in encryted password files (safes). It
33
- operates on the file specified in the environment variable PWS or on "~/.pws".
34
- You can apply a namespace as first parameter that will be appended to the
35
- filename, e.g. `pws -work show` with usual env would use "~/.pws-work".
36
-
37
- #{Paint["Available actions", :underline]}
38
-
39
- #{Paint['ls', :bold]} / list / show / status
40
- Lists all available password entries.
41
-
42
- #{Paint['add', :bold]} / set / store / create ( name, password = nil )
43
- Stores a new password entry. The second argument can be the password, but
44
- it's recommended to not pass it, but enter it interactively.
45
-
46
- #{Paint['get', :bold]} / entry / copy / password / for ( name, seconds = 10 )
47
- Copies the password for <name> to the clipboard. The second argument specifies,
48
- how long the password is kept in the clipboard (0 = no deletion).
49
-
50
- #{Paint['gen', :bold]} / generate ( name, seconds = 10, length = 64, char_pool )
51
- Generates a new password for <name> and then copies it to the clipboard, like
52
- get (the second argument is the time - it gets passed to get). The third
53
- argument sets the password length. The fourth argument allows you to pass a
54
- character pool that is used for generating the passwords.
55
-
56
- #{Paint['rm', :bold]} / remove / del / delete ( name )
57
- Removes a password entry.
58
-
59
- #{Paint['mv', :bold]} / move / rename ( old_name, new_name )
60
- Renames a password entry.
61
-
62
- #{Paint['master', :bold]} ( password = nil )
63
- Changes the master password.
64
-
65
- #{Paint['v', :bold]} / version
66
- Displays version and website.
67
-
68
- #{Paint['help', :bold]} / actions / commands
69
- Displays this help.
70
-
71
- HELP
72
- else # redirect to safe
73
- if PWS.public_instance_methods(false).include?(@action)
74
- PWS.new(nil, @namespace).send @action, *@args
75
- else
76
- pa "Unknown action: #@action\nPlease see `pws help` for a list of available commands!", :red
77
- end
78
- end
79
- rescue PWS::NoAccess
80
- # pa $!.message.capitalize, :red, :bold
81
- pa "NO ACCESS", :red, :bold
82
- rescue ArgumentError
83
- pa $!.message.capitalize, :red
84
- rescue Interrupt
85
- system 'stty echo' if $stdin.tty? # ensure terminal's working
86
- pa "..canceled", :red
87
- end
3
+ require_relative '../lib/pws/runner'
4
+ PWS::Runner.run(*PWS::Runner.parse_cli_arguments)
88
5
 
89
6
  # J-_-L
@@ -21,7 +21,18 @@ Feature: Generate
21
21
  Then the output should contain "Master password:"
22
22
  And the output should contain "The password for github has been added"
23
23
  And the output should contain "The password for github is now available in your clipboard for 1 second"
24
-
24
+
25
+ @wait-11s
26
+ @slow-hack
27
+ Scenario: Generate a new password for "github", PWS_SECONDS set to 5, gets passed to the get as keep-in-clipboard time
28
+ Given A safe exists with master password "my_master_password"
29
+ When I set env variable "PWS_SECONDS" to "5"
30
+ And I run `pws generate github` interactively
31
+ And I type "my_master_password"
32
+ Then the output should contain "Master password:"
33
+ And the output should contain "The password for github has been added"
34
+ And the output should contain "The password for github is now available in your clipboard for 5 seconds"
35
+
25
36
  @slow-hack
26
37
  Scenario: Generate a new password for "github", third parameter defines password length
27
38
  Given A safe exists with master password "my_master_password"
@@ -42,6 +53,17 @@ Feature: Generate
42
53
  And the output should contain "The password for github has been copied to your clipboard"
43
54
  And the clipboard should match /^.{64}$/
44
55
 
56
+ @slow-hack
57
+ Scenario: Generate a new password for "github", default length of PWS_GEN_LENGTH
58
+ Given A safe exists with master password "my_master_password"
59
+ When I set env variable "PWS_LENGTH" to "15"
60
+ And I run `pws generate github 0` interactively
61
+ And I type "my_master_password"
62
+ Then the output should contain "Master password:"
63
+ And the output should contain "The password for github has been added"
64
+ And the output should contain "The password for github has been copied to your clipboard"
65
+ And the clipboard should match /^.{15}$/
66
+
45
67
  @slow-hack
46
68
  Scenario: Generate a new password for "github", fourth parameter defines a char pool used for generation
47
69
  Given A safe exists with master password "my_master_password"
@@ -62,4 +84,15 @@ Feature: Generate
62
84
  And the output should contain "The password for github has been copied to your clipboard"
63
85
  And the clipboard should match ^[!\"\#$%&'()*+,\-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\[\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~]+$
64
86
 
65
-
87
+ @slow-hack
88
+ Scenario: Generate a new password for "github", the default char pool PWS_GEN_CHARPOOL
89
+ Given A safe exists with master password "my_master_password"
90
+ When I set env variable "PWS_CHARPOOL" to "a"
91
+ When I run `pws generate github 0` interactively
92
+ And I type "my_master_password"
93
+ Then the output should contain "Master password:"
94
+ And the output should contain "The password for github has been added"
95
+ And the output should contain "The password for github has been copied to your clipboard"
96
+ And the clipboard should match ^a{64}$
97
+
98
+
@@ -25,7 +25,16 @@ Feature: Get
25
25
  And I type "my_master_password"
26
26
  Then the output should contain "Master password:"
27
27
  And the output should contain "The password for github is now available in your clipboard for 1 second"
28
-
28
+
29
+ @wait-11s
30
+ Scenario: Get the password for "github" (which exists) and keep it in the clipboard for 5 seconds when PWS_SECONDS is set to 5
31
+ Given A safe exists with master password "my_master_password" and a key "github" with password "github_password"
32
+ When I set env variable "PWS_SECONDS" to "5"
33
+ And I run `pws get github` interactively
34
+ And I type "my_master_password"
35
+ Then the output should contain "Master password:"
36
+ And the output should contain "The password for github is now available in your clipboard for 5 seconds"
37
+
29
38
  Scenario: Get the password for "github" (which exists) and ensure that the original clipboard content gets restored
30
39
  Given A safe exists with master password "my_master_password" and a key "github" with password "github_password"
31
40
  Given A clipboard content of "blubb"
@@ -15,6 +15,26 @@ Feature: Show
15
15
  And the output should contain "password"
16
16
  And the output should contain "entries"
17
17
 
18
+ Scenario: Show the list and filter for regex
19
+ Given A safe exists with master password "my_master_password" and keys
20
+ | some-abc | 123 |
21
+ | password-aDc! | 345 |
22
+ | entries | 678 |
23
+ When I run `pws show a.c` interactively
24
+ And I type "my_master_password"
25
+ Then the output should contain "Entries"
26
+ And the output should contain "some-abc"
27
+ And the output should contain "password-aDc!"
28
+
29
+ Scenario: Show the list and filter for regex, but regex is invalid
30
+ Given A safe exists with master password "my_master_password" and keys
31
+ | some-abc | 123 |
32
+ | password-aDc! | 345 |
33
+ | entries | 678 |
34
+ When I run `pws show "(("` interactively
35
+ And I type "my_master_password"
36
+ Then the output should contain "Invalid regex"
37
+
18
38
  Scenario: Show the list (but there is no entry yet)
19
39
  Given A safe exists with master password "my_master_password"
20
40
  When I run `pws show` interactively
@@ -1,6 +1,7 @@
1
1
  def create_safe(master, key_hash = {})
2
+ ENV["PWS_CHARPOOL"] = ENV["PWS_LENGTH"] = ENV["PWS_SECONDS"] = nil
2
3
  restore, $stdout = $stdout, StringIO.new # tmp silence $stdout
3
- pws = PWS.new ENV["PWS"], nil, master
4
+ pws = PWS.new(password: master)
4
5
  key_hash.each{ |key, password|
5
6
  pws.add key, password
6
7
  }
@@ -34,3 +35,7 @@ end
34
35
  Then /^the clipboard should match ([^\/].+)$/ do |expected|
35
36
  assert_matching_output(expected, Clipboard.paste)
36
37
  end
38
+
39
+ When /^I set env variable "(\w+)" to "([^"]*)"$/ do |var, value|
40
+ ENV[var] = value
41
+ end
@@ -21,7 +21,7 @@ END{
21
21
  }
22
22
 
23
23
  Around do |_, block|
24
- # NOTE: You cannot parallelize the tests, because they use the clipboard and the env var...
24
+ # NOTE: You cannot parallelize the tests, because they use the clipboard and the env vars...
25
25
  Clipboard.clear
26
26
  ENV["PWS"] = File.expand_path('pws-test-' + SecureRandom.uuid)
27
27
 
data/lib/pws.rb CHANGED
@@ -10,36 +10,56 @@ require 'paint/pa'
10
10
  class PWS
11
11
  class NoAccess < StandardError; end
12
12
 
13
+ attr_reader :filename, :options
14
+
13
15
  # Creates a new password safe. Takes the path to the password file, by default: ~/.pws
14
16
  # Second parameter allows namespaces that get appended to the file name (uses another safe)
15
17
  # You can pass the master password as third parameter (not recommended)
16
- def initialize(filename = nil, namespace = nil, password = nil)
17
- @pw_file = File.expand_path(filename || ENV["PWS"] || '~/.pws')
18
- @pw_file << namespace if namespace
19
- access_safe(password)
18
+ def initialize(options)
19
+ collect_options(options)
20
+ @filename = File.expand_path(@options[:filename])
21
+ @filename << '-' << @options[:namespace] if @options[:namespace]
22
+
23
+ access_safe(options[:password])
20
24
  read_safe
21
25
  end
22
26
 
27
+ def collect_options(options = {})
28
+ @options = options
29
+ @options[:filename] ||= ENV["PWS"] || '~/.pws'
30
+ @options[:seconds] ||= ENV['PWS_SECONDS'] || 10
31
+ @options[:length] ||= ENV['PWS_LENGTH'] || 64
32
+ @options[:charpool] ||= ENV['PWS_CHARPOOL'] || (33..126).map(&:chr).join
33
+ end
34
+
23
35
  # Shows a password entry list
24
- def show
25
- if @pw_data.empty?
26
- pa %[There aren't any passwords stored at #{@pw_file}, yet], :red
36
+ def show(pattern = nil)
37
+ if @data.empty?
38
+ pa %[There aren't any passwords stored at #{@filename}, yet], :red
27
39
  else
28
- puts Paint["Entries", :underline] + %[ in ] + @pw_file
29
- puts @pw_data.keys.sort.map{ |key| %[- #{key}\n] }.join
40
+ if pattern
41
+ keys = @data.keys.grep /#{pattern}/
42
+ else
43
+ keys = @data.keys
44
+ end
45
+ puts Paint["Entries", :underline] + %[ in ] + @filename
46
+ puts keys.sort.map{ |key| %[- #{key}\n] }.join
30
47
  end
31
48
  return true
49
+ rescue RegexpError
50
+ pa %[Invalid regex given], :red
51
+ return false
32
52
  end
33
53
  aliases_for :show, :ls, :list, :status
34
54
 
35
55
  # Add a password entry, params: name, password (optional, opens prompt if not given)
36
56
  def add(key, password = nil)
37
- if @pw_data[key]
57
+ if @data[key]
38
58
  pa %[There is already a password stored for #{key}. You need to remove it before creating a new one!], :red
39
59
  return false
40
60
  else
41
- @pw_data[key] = password || ask_for_password(%[please enter a password for #{key}], :yellow)
42
- if @pw_data[key].empty?
61
+ @data[key] = password || ask_for_password(%[please enter a password for #{key}], :yellow)
62
+ if @data[key].empty?
43
63
  pa %[Cannot add an empty password!], :red
44
64
  return false
45
65
  else
@@ -49,11 +69,11 @@ class PWS
49
69
  end
50
70
  end
51
71
  end
52
- aliases_for :add, :set, :store, :create, :[]= # using zucker/alias_for
72
+ aliases_for :add, :set, :store, :create, :[]=
53
73
 
54
74
  # Gets the password entry and copies it to the clipboard. The second parameter is the time in seconds it stays there
55
- def get(key, seconds = 10)
56
- if pw_plaintext = @pw_data[key]
75
+ def get(key, seconds = @options[:seconds])
76
+ if pw_plaintext = @data[key]
57
77
  if seconds && seconds.to_i > 0
58
78
  original_clipboard_content = Clipboard.paste
59
79
  Clipboard.copy pw_plaintext
@@ -81,13 +101,13 @@ class PWS
81
101
  # Adds a password entry with a freshly generated random password
82
102
  def generate(
83
103
  key,
84
- seconds = 10,
85
- length = 64,
86
- char_pool = (32..126).map(&:chr).join.gsub(/\s/, '')
104
+ seconds = @options[:seconds],
105
+ length = @options[:length],
106
+ charpool = @options[:charpool]
87
107
  )
88
- char_pool_size = char_pool.size
108
+ charpool_size = charpool.size
89
109
  new_pw = (1..length.to_i).map{
90
- char_pool[SecureRandom.random_number(char_pool_size)]
110
+ charpool[SecureRandom.random_number(charpool_size)]
91
111
  }.join
92
112
 
93
113
  if add(key, new_pw)
@@ -98,7 +118,7 @@ class PWS
98
118
 
99
119
  # Removes a specific password entry
100
120
  def remove(key)
101
- if @pw_data.delete key
121
+ if @data.delete key
102
122
  write_safe
103
123
  pa %[The password for #{key} has been removed], :green
104
124
  return true
@@ -111,14 +131,14 @@ class PWS
111
131
 
112
132
  # Removes a specific password entry
113
133
  def rename(old_key, new_key)
114
- if !@pw_data[old_key]
134
+ if !@data[old_key]
115
135
  pa %[No password found for #{old_key}!], :red
116
136
  return false
117
- elsif @pw_data[new_key]
137
+ elsif @data[new_key]
118
138
  pa %[There is already a password stored for #{new_key}. You need to remove it before naming another one #{new_key}!], :red
119
139
  return false
120
140
  else
121
- @pw_data[new_key] = @pw_data.delete(old_key)
141
+ @data[new_key] = @data.delete(old_key)
122
142
  write_safe
123
143
  pa %[The password entry #{old_key} has been renamed to #{new_key}], :green
124
144
  return true
@@ -136,7 +156,7 @@ class PWS
136
156
  return false
137
157
  end
138
158
  end
139
- @pw_hash = Encryptor.hash(password)
159
+ @hash = Encryptor.hash(password)
140
160
  write_safe
141
161
  pa %[The master password has been changed], :green
142
162
  return true
@@ -152,35 +172,40 @@ class PWS
152
172
 
153
173
  # Tries to load and decrypt the password safe from the pwfile
154
174
  def read_safe
155
- pwdata_raw = File.read(@pw_file)
175
+ pwdata_raw = File.read(@filename)
156
176
  pwdata_encrypted = pwdata_raw.force_encoding("ascii")
157
- pwdata_dump = Encryptor.decrypt(pwdata_encrypted, @pw_hash)
177
+ pwdata_dump = Encryptor.decrypt(pwdata_encrypted, @hash)
158
178
  pwdata_with_redundancy = Marshal.load(pwdata_dump)
159
- @pw_data = remove_redundancy(pwdata_with_redundancy)
179
+ @data = remove_redundancy(pwdata_with_redundancy)
160
180
  pa %[ACCESS GRANTED], :green
161
181
  rescue
162
182
  fail NoAccess, %[Could not load and decrypt the password safe!]
163
183
  end
164
184
 
165
185
  # Tries to encrypt and save the password safe into the pwfile
166
- def write_safe
167
- pwdata_with_redundancy = add_redundancy(@pw_data || {})
186
+ def write_safe(new_safe = false)
187
+ pwdata_with_redundancy = add_redundancy(@data || {})
168
188
  pwdata_dump = Marshal.dump(pwdata_with_redundancy)
169
- pwdata_encrypted = Encryptor.encrypt(pwdata_dump, @pw_hash)
170
- File.open(@pw_file, 'w'){ |f| f.write(pwdata_encrypted) }
189
+ pwdata_encrypted = Encryptor.encrypt(pwdata_dump, @hash)
190
+ if new_safe
191
+ FileUtils.mkdir_p(File.dirname(@filename))
192
+ FileUtils.touch(@filename)
193
+ File.chmod(0600, @filename)
194
+ end
195
+ File.open(@filename, 'w'){ |f| f.write(pwdata_encrypted) }
171
196
  rescue
172
197
  fail NoAccess, %[Could not encrypt and save the password safe!]
173
198
  end
174
199
 
175
200
  # Checks if the file is accessible or create a new one
176
201
  def access_safe(password = nil)
177
- if !File.file? @pw_file
178
- pa %[No password safe detected, creating one at #@pw_file], :blue, :bold
179
- @pw_hash = Encryptor.hash password || ask_for_password(%[please enter a new master password], :yellow, :bold)
180
- write_safe
202
+ if !File.file? @filename
203
+ pa %[No password safe detected, creating one at #@filename], :blue, :bold
204
+ @hash = Encryptor.hash password || ask_for_password(%[please enter a new master password], :yellow, :bold)
205
+ write_safe(true)
181
206
  else
182
- print %[Access password safe at #@pw_file | ]
183
- @pw_hash = Encryptor.hash password || ask_for_password(%[master password])
207
+ print %[Access password safe at #@filename | ]
208
+ @hash = Encryptor.hash password || ask_for_password(%[master password])
184
209
  end
185
210
  end
186
211
 
@@ -0,0 +1,111 @@
1
+ require_relative '../pws'
2
+
3
+ module PWS::Runner
4
+ class << self
5
+ # some simple option parsing
6
+ # returns action, arguments, options
7
+ # only accepts options with value as next arg, except breaking special cases
8
+ def parse_cli_arguments(argv = $*.dup)
9
+ action = nil
10
+ options = {}
11
+ arguments = []
12
+ argv.unshift(nil) # easier parsing
13
+
14
+ argv.each_cons(2){ |prev_arg, arg|
15
+ case arg
16
+ when '-'
17
+ # ignore
18
+ when /^--(help|version)$/
19
+ return [$1.to_sym, [], {}]
20
+ when /^--/
21
+ # parse option in next iteration
22
+ when /^-([^-].*)$/
23
+ options[:namespace] = $1
24
+ else
25
+ if prev_arg =~ /^--(.+)$/
26
+ options[$1.to_sym] = arg
27
+ elsif !action
28
+ action = arg.to_sym
29
+ else
30
+ arguments << arg
31
+ end
32
+ end
33
+ }
34
+
35
+ [action || :show, arguments, options]
36
+ end
37
+
38
+ # makes the Ruby safe more usable
39
+ def run(action, arguments, options)
40
+ case action
41
+ when :v, :version
42
+ puts "pws #{PWS::VERSION} by " + Paint["J-_-L", :bold] + " <https://github.com/janlelis/pws>"
43
+ when :help, :actions, :commands
44
+ puts(<<HELP)
45
+
46
+ #{Paint["Usage", :underline]}
47
+
48
+ #{Paint['pws', :bold]} [-namespace] action [arguments]
49
+
50
+ #{Paint["Info", :underline]}
51
+
52
+ pws allows you to manage passwords in encryted password files (safes). It
53
+ operates on the file specified in the environment variable PWS or on "~/.pws".
54
+ You can apply a namespace as first parameter that will be appended to the
55
+ filename, e.g. `pws -work show` with usual env would use "~/.pws-work".
56
+
57
+ #{Paint["Available actions", :underline]}
58
+
59
+ #{Paint['ls', :bold]} / list / show / status ( pattern = nil )
60
+ Lists all available password entries. Optionally takes a regex filter.
61
+
62
+ #{Paint['add', :bold]} / set / store / create ( name, password = nil )
63
+ Stores a new password entry. The second argument can be the password, but
64
+ it's recommended to not pass it, but enter it interactively.
65
+
66
+ #{Paint['get', :bold]} / entry / copy / password / for ( name, seconds = 10 )
67
+ Copies the password for <name> to the clipboard. The second argument specifies,
68
+ how long the password is kept in the clipboard (0 = no deletion).
69
+
70
+ #{Paint['gen', :bold]} / generate ( name, seconds = 10, length = 64, char_pool )
71
+ Generates a new password for <name> and then copies it to the clipboard, like
72
+ get (the second argument is the time - it gets passed to get). The third
73
+ argument sets the password length. The fourth argument allows you to pass a
74
+ character pool that is used for generating the passwords.
75
+
76
+ #{Paint['rm', :bold]} / remove / del / delete ( name )
77
+ Removes a password entry.
78
+
79
+ #{Paint['mv', :bold]} / move / rename ( old_name, new_name )
80
+ Renames a password entry.
81
+
82
+ #{Paint['master', :bold]} ( password = nil )
83
+ Changes the master password.
84
+
85
+ #{Paint['v', :bold]} / version
86
+ Displays version and website.
87
+
88
+ #{Paint['help', :bold]} / actions / commands
89
+ Displays this help.
90
+
91
+ HELP
92
+ else # redirect to safe
93
+ if PWS.public_instance_methods(false).include?(action)
94
+ PWS.new(options).public_send(action, *arguments)
95
+ else
96
+ pa "Unknown action: #{action}\nPlease see `pws --help` for a list of available commands!", :red
97
+ end
98
+ end
99
+ rescue PWS::NoAccess
100
+ # pa $!.message.capitalize, :red, :bold
101
+ pa "NO ACCESS", :red, :bold
102
+ rescue ArgumentError
103
+ pa $!.message.capitalize, :red
104
+ rescue Interrupt
105
+ system 'stty echo' if $stdin.tty? # ensure terminal's working
106
+ pa "..canceled", :red
107
+ end
108
+ end
109
+ end
110
+
111
+ # J-_-L
@@ -1,3 +1,3 @@
1
1
  class PWS
2
- VERSION = '0.9.1'
2
+ VERSION = '0.9.2'.dup
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pws
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.1
4
+ version: 0.9.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-24 00:00:00.000000000 Z
12
+ date: 2012-04-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: clipboard
16
- requirement: &13917980 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,15 @@ dependencies:
21
21
  version: 1.0.1
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *13917980
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 1.0.1
25
30
  - !ruby/object:Gem::Dependency
26
31
  name: zucker
27
- requirement: &13916940 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
28
33
  none: false
29
34
  requirements:
30
35
  - - ! '>='
@@ -32,10 +37,15 @@ dependencies:
32
37
  version: '12.1'
33
38
  type: :runtime
34
39
  prerelease: false
35
- version_requirements: *13916940
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '12.1'
36
46
  - !ruby/object:Gem::Dependency
37
47
  name: paint
38
- requirement: &13887320 !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
39
49
  none: false
40
50
  requirements:
41
51
  - - ! '>='
@@ -43,10 +53,15 @@ dependencies:
43
53
  version: 0.8.4
44
54
  type: :runtime
45
55
  prerelease: false
46
- version_requirements: *13887320
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: 0.8.4
47
62
  - !ruby/object:Gem::Dependency
48
63
  name: rake
49
- requirement: &13886440 !ruby/object:Gem::Requirement
64
+ requirement: !ruby/object:Gem::Requirement
50
65
  none: false
51
66
  requirements:
52
67
  - - ! '>='
@@ -54,10 +69,15 @@ dependencies:
54
69
  version: '0'
55
70
  type: :development
56
71
  prerelease: false
57
- version_requirements: *13886440
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
58
78
  - !ruby/object:Gem::Dependency
59
79
  name: cucumber
60
- requirement: &13885760 !ruby/object:Gem::Requirement
80
+ requirement: !ruby/object:Gem::Requirement
61
81
  none: false
62
82
  requirements:
63
83
  - - ! '>='
@@ -65,10 +85,15 @@ dependencies:
65
85
  version: '0'
66
86
  type: :development
67
87
  prerelease: false
68
- version_requirements: *13885760
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
69
94
  - !ruby/object:Gem::Dependency
70
95
  name: aruba
71
- requirement: &13885120 !ruby/object:Gem::Requirement
96
+ requirement: !ruby/object:Gem::Requirement
72
97
  none: false
73
98
  requirements:
74
99
  - - ! '>='
@@ -76,7 +101,12 @@ dependencies:
76
101
  version: '0'
77
102
  type: :development
78
103
  prerelease: false
79
- version_requirements: *13885120
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
80
110
  description: pws is a command-line password safe. Please run `pws help` for usage
81
111
  information.
82
112
  email: mail@janlelis.de
@@ -87,22 +117,23 @@ extra_rdoc_files:
87
117
  - README.md
88
118
  - LICENSE
89
119
  files:
90
- - lib/pws/encryptor.rb
91
120
  - lib/pws/version.rb
121
+ - lib/pws/encryptor.rb
122
+ - lib/pws/runner.rb
92
123
  - lib/pws.rb
93
124
  - bin/pws
94
- - features/step_definitions/pws_steps.rb
95
- - features/remove.feature
96
- - features/namespaces.feature
97
- - features/generate.feature
98
- - features/rename.feature
99
125
  - features/show.feature
100
- - features/add.feature
101
126
  - features/access.feature
102
- - features/master.feature
127
+ - features/misc.feature
103
128
  - features/get.feature
129
+ - features/master.feature
130
+ - features/remove.feature
131
+ - features/namespaces.feature
132
+ - features/add.feature
104
133
  - features/support/env.rb
105
- - features/misc.feature
134
+ - features/rename.feature
135
+ - features/generate.feature
136
+ - features/step_definitions/pws_steps.rb
106
137
  - Rakefile
107
138
  - pws.gemspec
108
139
  - README.md
@@ -130,7 +161,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
130
161
  version: '0'
131
162
  requirements: []
132
163
  rubyforge_project:
133
- rubygems_version: 1.8.11
164
+ rubygems_version: 1.8.23
134
165
  signing_key:
135
166
  specification_version: 3
136
167
  summary: pws is a cli password safe.