rubeepass 0.5.3 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 797e4b5d5f2b72f43feef99f141440eee6890f0e
4
- data.tar.gz: efcd65291652a76394b9f56d93158a5980ed0720
3
+ metadata.gz: 6cd12a155f8a2bcbc5da07aee0406bcd4040ca4b
4
+ data.tar.gz: 506e2a4064b4ae4f0a2fb3d46eae776aea0a6265
5
5
  SHA512:
6
- metadata.gz: c0447457c9a9b99eadd8e11efdaa3cdeb204293a37b28942de7f7b8053b2ce1ef24deb0c29cc644529f65c223b077ac6d003165ddce5c86eff573fab3c044292
7
- data.tar.gz: 7ec1c0f82ae395a5dbd37d26bc38aeb6cfe38898ded1d7e230b20042ad9e45f8970396b7e0773aba9452e7866b65336a4e59b96c00530b8c335a67b3a2c82a7d
6
+ metadata.gz: 0f80638206bbc1e018eb631a219898620c15bc2ca7f6210960638c70a3276059a2749e9156a3ab7e0477ea4adc209b8236c5af1d9ae16e8fb149ce82b998693a
7
+ data.tar.gz: 6719b71656475fe4dabf4ac4e41db654f8baa3429decc2a62477335eaddb717c5931939b3e48d15f7a1da52ca494086231b4285876c5860c33f9d74d74af27d3
data/bin/rpass CHANGED
@@ -277,6 +277,7 @@ rescue RubeePass::Error => e
277
277
  puts e.message
278
278
  exit RubeePassExit::EXCEPTION
279
279
  rescue Exception => e
280
+ $stderr.puts
280
281
  $stderr.puts "Oops! Looks like an error has occured! If the " \
281
282
  "error persists, file a bug at:".word_wrap
282
283
  $stderr.puts
@@ -1,17 +1,12 @@
1
1
  require "colorize"
2
2
  require "rexml/document"
3
- require "string"
4
3
 
5
4
  class RubeePass::Entry
6
5
  include Comparable
7
6
 
8
7
  attr_accessor :group
9
8
  attr_accessor :keepass
10
- attr_accessor :notes
11
9
  attr_accessor :path
12
- attr_accessor :title
13
- attr_accessor :url
14
- attr_accessor :username
15
10
  attr_accessor :uuid
16
11
 
17
12
  def ==(other)
@@ -72,12 +67,16 @@ class RubeePass::Entry
72
67
  uuid = "" if (uuid.nil?)
73
68
 
74
69
  xml.elements.each("String") do |elem|
70
+ value = elem.elements["Value"]
75
71
  case elem.elements["Key"].text
76
72
  when "Notes"
77
- notes = elem.elements["Value"].text
78
- notes = "" if (notes.nil?)
73
+ if (value.attributes["Protected"] == "True")
74
+ notes = handle_protected(keepass, value.text)
75
+ else
76
+ notes = value.text
77
+ notes = "" if (notes.nil?)
78
+ end
79
79
  when "Password"
80
- value = elem.elements["Value"]
81
80
  if (value.attributes["Protected"] == "True")
82
81
  password = handle_protected(keepass, value.text)
83
82
  else
@@ -85,14 +84,26 @@ class RubeePass::Entry
85
84
  password = "" if (password.nil?)
86
85
  end
87
86
  when "Title"
88
- title = elem.elements["Value"].text
89
- title = "" if (title.nil?)
87
+ if (value.attributes["Protected"] == "True")
88
+ title = handle_protected(keepass, value.text)
89
+ else
90
+ title = value.text
91
+ title = "" if (title.nil?)
92
+ end
90
93
  when "URL"
91
- url = elem.elements["Value"].text
92
- url = "" if (url.nil?)
94
+ if (value.attributes["Protected"] == "True")
95
+ url = handle_protected(keepass, value.text)
96
+ else
97
+ url = value.text
98
+ url = "" if (url.nil?)
99
+ end
93
100
  when "UserName"
94
- username = elem.elements["Value"].text
95
- username = "" if (username.nil?)
101
+ if (value.attributes["Protected"] == "True")
102
+ username = handle_protected(keepass, value.text)
103
+ else
104
+ username = value.text
105
+ username = "" if (username.nil?)
106
+ end
96
107
  end
97
108
  end
98
109
 
@@ -119,8 +130,11 @@ class RubeePass::Entry
119
130
  data = nil
120
131
  return nil if (base64.nil?)
121
132
  begin
122
- data = base64.unpack("m*")[0].fix
123
- rescue ArgumentError => e
133
+ data = base64.unpack("m*")[0]
134
+ if (data.length != data.bytesize)
135
+ data = data.unpack("H*").pack("H*")
136
+ end
137
+ rescue ArgumentError
124
138
  raise Error::InvalidProtectedData.new
125
139
  end
126
140
  raise Error::InvalidProtectedData.new if (data.nil?)
@@ -186,6 +200,16 @@ class RubeePass::Entry
186
200
  end
187
201
  end
188
202
 
203
+ def notes
204
+ return nil if (@keepass.nil?)
205
+ return "" if (@notes.nil?)
206
+ begin
207
+ return @keepass.protected_decryptor.get_password(@notes)
208
+ rescue
209
+ return @notes
210
+ end
211
+ end
212
+
189
213
  def password
190
214
  return nil if (@keepass.nil?)
191
215
  return "" if (@password.nil?)
@@ -198,6 +222,38 @@ class RubeePass::Entry
198
222
  end
199
223
  end
200
224
 
225
+ def title
226
+ return nil if (@keepass.nil?)
227
+ return "" if (@title.nil?)
228
+ begin
229
+ return @keepass.protected_decryptor.get_password(@title)
230
+ rescue
231
+ return @title
232
+ end
233
+ end
234
+
235
+ def url
236
+ return nil if (@keepass.nil?)
237
+ return "" if (@url.nil?)
238
+ begin
239
+ return @keepass.protected_decryptor.get_password(@url)
240
+ rescue
241
+ return @url
242
+ end
243
+ end
244
+
245
+ def username
246
+ return nil if (@keepass.nil?)
247
+ return "" if (@username.nil?)
248
+ begin
249
+ return @keepass.protected_decryptor.get_password(
250
+ @username
251
+ )
252
+ rescue
253
+ return @username
254
+ end
255
+ end
256
+
201
257
  def to_s
202
258
  return details
203
259
  end
@@ -1,5 +1,3 @@
1
- require "rubeepass/error"
2
-
3
1
  class RubeePass::Error::InvalidGzip < RubeePass::Error
4
2
  def initialize
5
3
  super("Invalid gzip format!")
@@ -1,5 +1,3 @@
1
- require "rubeepass/error"
2
-
3
1
  class RubeePass::Error::InvalidHeader < RubeePass::Error
4
2
  def initialize
5
3
  super("Invalid header format!")
@@ -1,5 +1,3 @@
1
- require "rubeepass/error"
2
-
3
1
  class RubeePass::Error::InvalidMagic < RubeePass::Error
4
2
  def initialize
5
3
  super("Invalid magic values detected!")
@@ -1,5 +1,3 @@
1
- require "rubeepass/error"
2
-
3
1
  class RubeePass::Error::InvalidPassword < RubeePass::Error
4
2
  def initialize
5
3
  super("Invalid password provided!")
@@ -1,5 +1,3 @@
1
- require "rubeepass/error"
2
-
3
1
  class RubeePass::Error::InvalidProtectedData < RubeePass::Error
4
2
  def initialize
5
3
  super("Invalid protected data!")
@@ -1,5 +1,3 @@
1
- require "rubeepass/error"
2
-
3
1
  class RubeePass::Error::InvalidProtectedStreamKey < RubeePass::Error
4
2
  def initialize
5
3
  super("Invalid protected stream key!")
@@ -1,5 +1,3 @@
1
- require "rubeepass/error"
2
-
3
1
  class RubeePass::Error::InvalidVersion < RubeePass::Error
4
2
  def initialize
5
3
  super("Invalid version detected!")
@@ -1,5 +1,3 @@
1
- require "rubeepass/error"
2
-
3
1
  class RubeePass::Error::InvalidXML < RubeePass::Error
4
2
  def initialize
5
3
  super("Invalid xml schema!")
@@ -1,5 +1,3 @@
1
- require "rubeepass/error"
2
-
3
1
  class RubeePass::Error::NotAES < RubeePass::Error
4
2
  def initialize
5
3
  super("Not AES!")
@@ -1,5 +1,3 @@
1
- require "rubeepass/error"
2
-
3
1
  class RubeePass::Error::NotSalsa20 < RubeePass::Error
4
2
  def initialize
5
3
  super("Not a Salsa20 CrsAlgorithm!")
@@ -49,7 +49,9 @@ class RubeePass::Group
49
49
  end
50
50
 
51
51
  def entry_titles
52
- return @entries.keys.sort
52
+ return @entries.keys.sort do |a, b|
53
+ a.downcase <=> b.downcase
54
+ end
53
55
  end
54
56
 
55
57
  def find_group(path)
@@ -116,41 +118,42 @@ class RubeePass::Group
116
118
  return group
117
119
  end
118
120
 
119
- def fuzzy_find(input)
120
- return [ [], [], [] ] if (@keepass.nil?)
121
+ def fuzzy_find(search)
122
+ return [[], []] if (@keepass.nil?)
121
123
 
122
- input = @path if (input.nil? || input.empty?)
123
- input = @keepass.absolute_path(input, @path)
124
- path, target = input.rsplit("/")
124
+ search = @path if (search.nil? || search.empty?)
125
+ search = @keepass.absolute_path(search, @path)
126
+ path, target = search.rsplit("/")
125
127
 
126
128
  new_cwd = find_group(path)
127
- return [ input, [], [] ] if (new_cwd.nil?)
129
+ return [[], []] if (new_cwd.nil?)
128
130
 
129
131
  if (new_cwd.has_group?(target))
130
132
  new_cwd = new_cwd.groups[target]
131
133
  target = ""
132
- input += "/"
133
134
  end
134
135
 
135
136
  group_completions = new_cwd.group_names
136
137
  entry_completions = new_cwd.entry_titles
137
138
 
138
139
  if (target.empty?)
139
- return [ input, group_completions, entry_completions ]
140
+ return [group_completions, entry_completions]
140
141
  end
141
142
 
142
- group_completions.delete_if do |group|
143
- !group.downcase.start_with?(target.downcase)
143
+ group_completions.keep_if do |group|
144
+ group.downcase.start_with?(target.downcase)
144
145
  end
145
- entry_completions.delete_if do |entry|
146
- !entry.downcase.start_with?(target.downcase)
146
+ entry_completions.keep_if do |entry|
147
+ entry.downcase.start_with?(target.downcase)
147
148
  end
148
149
 
149
- return [ input, group_completions, entry_completions ]
150
+ return [group_completions, entry_completions]
150
151
  end
151
152
 
152
153
  def group_names
153
- return @groups.keys.sort
154
+ return @groups.keys.sort do |a, b|
155
+ a.downcase <=> b.downcase
156
+ end
154
157
  end
155
158
 
156
159
  def has_entry?(title)
@@ -3,7 +3,7 @@ require "djinni"
3
3
 
4
4
  class CDWish < Djinni::Wish
5
5
  def aliases
6
- return [ "cd" ]
6
+ return ["cd"]
7
7
  end
8
8
 
9
9
  def description
@@ -15,47 +15,37 @@ class CDWish < Djinni::Wish
15
15
  cwd = djinni_env["cwd"]
16
16
  prompt_color = djinni_env["prompt_color"]
17
17
 
18
- args = keepass.absolute_path(args, cwd.path)
19
- new_cwd = keepass.find_group(args)
20
-
21
- if (new_cwd)
22
- djinni_env["cwd"] = new_cwd
23
- if (prompt_color)
24
- prompt = "rpass:#{new_cwd.name}> ".send(prompt_color)
25
- else
26
- prompt = "rpass:#{new_cwd.name}> "
27
- end
28
- djinni_env["djinni_prompt"] = prompt
18
+ path = keepass.absolute_path(args, cwd.path)
19
+ new_cwd = keepass.find_group(path)
20
+
21
+ if (new_cwd.nil?)
22
+ puts "Group not found"
23
+ return
24
+ end
25
+
26
+ djinni_env["cwd"] = new_cwd
27
+ if (prompt_color)
28
+ prompt = "rpass:#{new_cwd.name}> ".send(prompt_color)
29
29
  else
30
- puts "Group \"#{args}\" doesn't exist!"
30
+ prompt = "rpass:#{new_cwd.name}> "
31
31
  end
32
+ djinni_env["djinni_prompt"] = prompt
32
33
  end
33
34
 
34
35
  def tab_complete(input, djinni_env = {})
35
36
  cwd = djinni_env["cwd"]
36
- input, groups = cwd.fuzzy_find(input)
37
- return input.gsub(%r{^#{cwd.path}/?}, "") if (groups.empty?)
38
-
39
- path, dest = input.rsplit("/")
40
-
41
- if (dest.empty?)
42
- if (groups.length == 1)
43
- input = "#{path}/#{groups.first}/"
44
- return input.gsub(%r{^#{cwd.path}/?}, "")
45
- end
46
- puts
47
- groups.each do |group|
48
- puts "#{group}/"
49
- end
50
- return input.gsub(%r{^#{cwd.path}/?}, "")
37
+ groups, entries = cwd.fuzzy_find(input)
38
+
39
+ completions = Hash.new
40
+ groups.each do |group|
41
+ completions[group] = "Group"
51
42
  end
52
43
 
53
- input = "#{path}/#{groups.first}/"
54
- return input.gsub(%r{^#{cwd.path}/?}, "")
44
+ return [completions, input.rsplit("/")[1], "/"]
55
45
  end
56
46
 
57
47
  def usage
58
48
  puts "#{aliases.join(", ")} [group]"
59
- puts "\t#{description}."
49
+ puts " #{description}."
60
50
  end
61
51
  end
@@ -2,7 +2,7 @@ require "djinni"
2
2
 
3
3
  class CopyWish < Djinni::Wish
4
4
  def aliases
5
- return [ "copy", "cp" ]
5
+ return ["copy", "cp"]
6
6
  end
7
7
 
8
8
  def description
@@ -10,129 +10,103 @@ class CopyWish < Djinni::Wish
10
10
  end
11
11
 
12
12
  def execute(args, djinni_env = {})
13
- if (args.nil? || args.empty?)
14
- puts usage
15
- return
16
- end
17
-
18
- field, args = args.split(" ", 2)
19
- if (!@fields.include?(field))
20
- puts usage
21
- return
22
- end
23
-
24
- if (ENV["DISPLAY"].nil? || ENV["DISPLAY"].empty?)
25
- puts "DISPLAY not set!"
13
+ # "".split(" ", 2) => [] aka [nil, nil]
14
+ # " ".split(" ", 2) => [""] aka ["", nil]
15
+ # "pass".split(" ", 2) => ["pass"] aka ["pass", nil]
16
+ # "pass ".split(" ", 2) => ["pass", ""]
17
+
18
+ field, path = args.split(" ", 2)
19
+ if (
20
+ field.nil? ||
21
+ field.empty? ||
22
+ !@fields.include?(field) ||
23
+ path.nil? ||
24
+ path.empty?
25
+ )
26
+ usage
26
27
  return
27
28
  end
28
29
 
29
30
  keepass = djinni_env["keepass"]
30
31
  cwd = djinni_env["cwd"]
31
- args = cwd.path if (args.nil? || args.empty?)
32
32
 
33
- args = keepass.absolute_path(args, cwd.path)
34
- path, target = args.rsplit("/")
33
+ path = keepass.absolute_path(path, cwd.path)
34
+ path, target = path.rsplit("/")
35
35
  new_cwd = keepass.find_group(path)
36
+ timeout = djinni_env["clipboard_timeout"]
36
37
 
37
- if (new_cwd)
38
- if (target.empty?)
39
- usage
40
- elsif (new_cwd.has_entry?(target))
41
- target = new_cwd.entry_titles.select do |entry|
42
- target.downcase == entry.downcase
43
- end.first
44
-
45
- timeout = djinni_env["clipboard_timeout"]
46
-
47
- case field
48
- when "pass"
49
- new_cwd.entries[target].copy_password_to_clipboard
50
- keepass.send(
51
- "clear_clipboard_after_#{timeout}_seconds"
52
- )
53
- when "url"
54
- new_cwd.entries[target].copy_url_to_clipboard
55
- keepass.send(
56
- "clear_clipboard_after_#{timeout}_seconds"
57
- )
58
- when "user"
59
- new_cwd.entries[target].copy_username_to_clipboard
60
- keepass.send(
61
- "clear_clipboard_after_#{timeout}_seconds"
62
- )
63
- end
64
- else
65
- puts "Entry \"#{args}\" doesn't exist!"
66
- end
67
- else
68
- puts "Entry \"#{args}\" doesn't exist!"
38
+ if (new_cwd.nil? || !new_cwd.has_entry?(target))
39
+ puts "Entry not found"
40
+ return
41
+ end
42
+
43
+ case field
44
+ when "pass"
45
+ new_cwd.entries[target].copy_password_to_clipboard
46
+ keepass.send(
47
+ "clear_clipboard_after_#{timeout}_seconds"
48
+ )
49
+ when "url"
50
+ new_cwd.entries[target].copy_url_to_clipboard
51
+ keepass.send(
52
+ "clear_clipboard_after_#{timeout}_seconds"
53
+ )
54
+ when "user"
55
+ new_cwd.entries[target].copy_username_to_clipboard
56
+ keepass.send(
57
+ "clear_clipboard_after_#{timeout}_seconds"
58
+ )
69
59
  end
70
60
  end
71
61
 
72
62
  def initialize
73
- @fields = [ "pass", "url", "user" ]
63
+ @fields = {
64
+ "pass" => "Password",
65
+ "url" => "URL",
66
+ "user" => "Username"
67
+ }
74
68
  end
75
69
 
76
70
  def tab_complete(input, djinni_env = {})
77
- if (input.nil? || input.empty?)
78
- puts
79
- puts @fields
80
- return ""
81
- end
71
+ # "".split(" ", 2) => [] aka [nil, nil]
72
+ # " ".split(" ", 2) => [""] aka ["", nil]
73
+ # "pass".split(" ", 2) => ["pass"] aka ["pass", nil]
74
+ # "pass ".split(" ", 2) => ["pass", ""]
82
75
 
83
- field, input = input.split(" ", 2)
76
+ field, path = input.split(" ", 2)
77
+ return [@fields, "", ""] if (field.nil? || field.empty?)
84
78
 
85
- if (input.nil? || input.empty?)
86
- @fields.each do |f|
87
- break if (f == field)
88
- if (f.start_with?(field))
89
- return "#{f} "
90
- end
79
+ if (path.nil?)
80
+ completions = @fields.select do |f, d|
81
+ f.start_with?(field)
91
82
  end
83
+ return [completions, field, " "]
92
84
  end
93
85
 
94
- input = "" if (input.nil?)
95
-
96
86
  cwd = djinni_env["cwd"]
97
- input, groups, entries = cwd.fuzzy_find(input)
98
- if (groups.empty? && entries.empty?)
99
- return "#{field} #{input.gsub(%r{^#{cwd.path}/?}, "")}"
100
- end
101
-
102
- path, target = input.rsplit("/")
87
+ groups, entries = cwd.fuzzy_find(path)
103
88
 
104
- if (target.empty?)
105
- if ((groups.length == 1) && entries.empty?)
106
- input = "#{path}/#{groups.first}/"
107
- return "#{field} #{input.gsub(%r{^#{cwd.path}/?}, "")}"
108
- elsif (groups.empty? && (entries.length == 1))
109
- input = "#{path}/#{entries.first}"
110
- return "#{field} #{input.gsub(%r{^#{cwd.path}/?}, "")}"
111
- end
112
- puts
113
- groups.each do |group|
114
- puts "#{group}/"
115
- end
116
- puts entries
117
- return "#{field} #{input.gsub(%r{^#{cwd.path}/?}, "")}"
89
+ completions = Hash.new
90
+ groups.each do |group|
91
+ completions[group] = "Group"
118
92
  end
119
-
120
- if (!groups.empty?)
121
- input = "#{path}/#{groups.first}/"
122
- elsif (!entries.empty?)
123
- input = "#{path}/#{entries.first}"
93
+ entries.each do |entry|
94
+ completions[entry] = "Entry"
124
95
  end
125
96
 
126
- return "#{field} #{input.gsub(%r{^#{cwd.path}/?}, "")}"
97
+ append = "/"
98
+ append = "" if (groups.empty?)
99
+
100
+ return [completions, path.rsplit("/")[1], append]
127
101
  end
128
102
 
129
103
  def usage
130
104
  puts "#{aliases.join(", ")} <field> <entry>"
131
- puts "\t#{description}."
105
+ puts " #{description}."
132
106
  puts
133
107
  puts "FIELDS"
134
- @fields.each do |field|
135
- puts "\t#{field}"
108
+ @fields.each do |field, desc|
109
+ puts " #{field}"
136
110
  end
137
111
  end
138
112
  end
@@ -2,7 +2,7 @@ require "djinni"
2
2
 
3
3
  class EchoWish < Djinni::Wish
4
4
  def aliases
5
- return [ "echo" ]
5
+ return ["echo"]
6
6
  end
7
7
 
8
8
  def description
@@ -10,113 +10,93 @@ class EchoWish < Djinni::Wish
10
10
  end
11
11
 
12
12
  def execute(args, djinni_env = {})
13
- if (args.nil? || args.empty?)
14
- puts usage
15
- return
16
- end
17
-
18
- field, args = args.split(" ", 2)
19
- if (!@fields.include?(field))
20
- puts usage
13
+ # "".split(" ", 2) => [] aka [nil, nil]
14
+ # " ".split(" ", 2) => [""] aka ["", nil]
15
+ # "pass".split(" ", 2) => ["pass"] aka ["pass", nil]
16
+ # "pass ".split(" ", 2) => ["pass", ""]
17
+
18
+ field, path = args.split(" ", 2)
19
+ if (
20
+ field.nil? ||
21
+ field.empty? ||
22
+ !@fields.include?(field) ||
23
+ path.nil? ||
24
+ path.empty?
25
+ )
26
+ usage
21
27
  return
22
28
  end
23
29
 
24
30
  keepass = djinni_env["keepass"]
25
31
  cwd = djinni_env["cwd"]
26
- args = cwd.path if (args.nil? || args.empty?)
27
32
 
28
- args = keepass.absolute_path(args, cwd.path)
29
- path, target = args.rsplit("/")
33
+ path = keepass.absolute_path(path, cwd.path)
34
+ path, target = path.rsplit("/")
30
35
  new_cwd = keepass.find_group(path)
31
36
 
32
- if (new_cwd)
33
- if (target.empty?)
34
- usage
35
- elsif (new_cwd.has_entry?(target))
36
- target = new_cwd.entry_titles.select do |entry|
37
- target.downcase == entry.downcase
38
- end.first
39
-
40
- case field
41
- when "pass"
42
- new_cwd.entries[target].echo_password
43
- when "url"
44
- new_cwd.entries[target].echo_url
45
- when "user"
46
- new_cwd.entries[target].echo_username
47
- end
48
- else
49
- puts "Entry \"#{args}\" doesn't exist!"
50
- end
51
- else
52
- puts "Entry \"#{args}\" doesn't exist!"
37
+ if (new_cwd.nil? || !new_cwd.has_entry?(target))
38
+ puts "Entry not found"
39
+ return
40
+ end
41
+
42
+ case field
43
+ when "pass"
44
+ new_cwd.entries[target].echo_password
45
+ when "url"
46
+ new_cwd.entries[target].echo_url
47
+ when "user"
48
+ new_cwd.entries[target].echo_username
53
49
  end
54
50
  end
55
51
 
56
52
  def initialize
57
- @fields = [ "pass", "url", "user" ]
53
+ @fields = {
54
+ "pass" => "Password",
55
+ "url" => "URL",
56
+ "user" => "Username"
57
+ }
58
58
  end
59
59
 
60
60
  def tab_complete(input, djinni_env = {})
61
- if (input.nil? || input.empty?)
62
- puts
63
- puts @fields
64
- return ""
65
- end
61
+ # "".split(" ", 2) => [] aka [nil, nil]
62
+ # " ".split(" ", 2) => [""] aka ["", nil]
63
+ # "pass".split(" ", 2) => ["pass"] aka ["pass", nil]
64
+ # "pass ".split(" ", 2) => ["pass", ""]
66
65
 
67
- field, input = input.split(" ", 2)
66
+ field, path = input.split(" ", 2)
67
+ return [@fields, "", ""] if (field.nil? || field.empty?)
68
68
 
69
- if (input.nil? || input.empty?)
70
- @fields.each do |f|
71
- break if (f == field)
72
- if (f.start_with?(field))
73
- return "#{f} "
74
- end
69
+ if (path.nil?)
70
+ completions = @fields.select do |f, d|
71
+ f.start_with?(field)
75
72
  end
73
+ return [completions, field, " "]
76
74
  end
77
75
 
78
- input = "" if (input.nil?)
79
-
80
76
  cwd = djinni_env["cwd"]
81
- input, groups, entries = cwd.fuzzy_find(input)
82
- if (groups.empty? && entries.empty?)
83
- return "#{field} #{input.gsub(%r{^#{cwd.path}/?}, "")}"
84
- end
77
+ groups, entries = cwd.fuzzy_find(path)
85
78
 
86
- path, target = input.rsplit("/")
87
-
88
- if (target.empty?)
89
- if ((groups.length == 1) && entries.empty?)
90
- input = "#{path}/#{groups.first}/"
91
- return "#{field} #{input.gsub(%r{^#{cwd.path}/?}, "")}"
92
- elsif (groups.empty? && (entries.length == 1))
93
- input = "#{path}/#{entries.first}"
94
- return "#{field} #{input.gsub(%r{^#{cwd.path}/?}, "")}"
95
- end
96
- puts
97
- groups.each do |group|
98
- puts "#{group}/"
99
- end
100
- puts entries
101
- return "#{field} #{input.gsub(%r{^#{cwd.path}/?}, "")}"
79
+ completions = Hash.new
80
+ groups.each do |group|
81
+ completions[group] = "Group"
102
82
  end
103
-
104
- if (!groups.empty?)
105
- input = "#{path}/#{groups.first}/"
106
- elsif (!entries.empty?)
107
- input = "#{path}/#{entries.first}"
83
+ entries.each do |entry|
84
+ completions[entry] = "Entry"
108
85
  end
109
86
 
110
- return "#{field} #{input.gsub(%r{^#{cwd.path}/?}, "")}"
87
+ append = "/"
88
+ append = "" if (groups.empty?)
89
+
90
+ return [completions, path.rsplit("/")[1], append]
111
91
  end
112
92
 
113
93
  def usage
114
94
  puts "#{aliases.join(", ")} <field> <entry>"
115
- puts "\t#{description}."
95
+ puts " #{description}."
116
96
  puts
117
97
  puts "FIELDS"
118
- @fields.each do |field|
119
- puts "\t#{field}"
98
+ @fields.each do |field, desc|
99
+ puts " #{field}"
120
100
  end
121
101
  end
122
102
  end
@@ -2,7 +2,7 @@ require "djinni"
2
2
 
3
3
  class LSWish < Djinni::Wish
4
4
  def aliases
5
- return [ "ls", "dir" ]
5
+ return ["ls", "dir"]
6
6
  end
7
7
 
8
8
  def description
@@ -12,48 +12,38 @@ class LSWish < Djinni::Wish
12
12
  def execute(args, djinni_env = {})
13
13
  keepass = djinni_env["keepass"]
14
14
  cwd = djinni_env["cwd"]
15
- args = cwd.path if (args.nil? || args.empty?)
16
-
17
- args = keepass.absolute_path(args, cwd.path)
18
- new_cwd = keepass.find_group(args)
19
-
20
- if (new_cwd)
21
- new_cwd.group_names.each do |group|
22
- puts "#{group}/"
23
- end
24
- new_cwd.entry_titles.each do |entry|
25
- puts "#{entry}"
26
- end
27
- else
28
- puts "Group \"#{args}\" doesn't exist!"
15
+
16
+ args = cwd.path if (args.empty?)
17
+ path = keepass.absolute_path(args, cwd.path)
18
+ new_cwd = keepass.find_group(path)
19
+
20
+ if (new_cwd.nil?)
21
+ puts "Group not found"
22
+ return
23
+ end
24
+
25
+ new_cwd.group_names.each do |group|
26
+ puts "#{group}/"
27
+ end
28
+ new_cwd.entry_titles.each do |entry|
29
+ puts "#{entry}"
29
30
  end
30
31
  end
31
32
 
32
33
  def tab_complete(input, djinni_env = {})
33
34
  cwd = djinni_env["cwd"]
34
- input, groups = cwd.fuzzy_find(input)
35
- return input.gsub(%r{^#{cwd.path}/?}, "") if (groups.empty?)
36
-
37
- path, dest = input.rsplit("/")
38
-
39
- if (dest.empty?)
40
- if (groups.length == 1)
41
- input = "#{path}/#{groups.first}/"
42
- return input.gsub(%r{^#{cwd.path}/?}, "")
43
- end
44
- puts
45
- groups.each do |group|
46
- puts "#{group}/"
47
- end
48
- return input.gsub(%r{^#{cwd.path}/?}, "")
35
+ groups, entries = cwd.fuzzy_find(input)
36
+
37
+ completions = Hash.new
38
+ groups.each do |group|
39
+ completions[group] = "Group"
49
40
  end
50
41
 
51
- input = "#{path}/#{groups.first}/"
52
- return input.gsub(%r{^#{cwd.path}/?}, "")
42
+ return [completions, input.rsplit("/")[1], "/"]
53
43
  end
54
44
 
55
45
  def usage
56
46
  puts "#{aliases.join(", ")} [group]"
57
- puts "\t#{description}."
47
+ puts " #{description}."
58
48
  end
59
49
  end
@@ -2,7 +2,7 @@ require "djinni"
2
2
 
3
3
  class PwdWish < Djinni::Wish
4
4
  def aliases
5
- return [ "pwd" ]
5
+ return ["pwd"]
6
6
  end
7
7
 
8
8
  def description
@@ -10,15 +10,12 @@ class PwdWish < Djinni::Wish
10
10
  end
11
11
 
12
12
  def execute(args, djinni_env = {})
13
- if (args.nil? || args.empty?)
14
- puts djinni_env["cwd"].path
15
- else
16
- usage
17
- end
13
+ puts djinni_env["cwd"].path if (args.empty?)
14
+ usage if (!args.empty?)
18
15
  end
19
16
 
20
17
  def usage
21
18
  puts aliases.join(", ")
22
- puts "\t#{description}."
19
+ puts " #{description}."
23
20
  end
24
21
  end
@@ -2,7 +2,7 @@ require "djinni"
2
2
 
3
3
  class ShowWish < Djinni::Wish
4
4
  def aliases
5
- return [ "cat", "show", "showall" ]
5
+ return ["cat", "show", "showall"]
6
6
  end
7
7
 
8
8
  def description
@@ -12,82 +12,67 @@ class ShowWish < Djinni::Wish
12
12
  def execute(args, djinni_env = {})
13
13
  keepass = djinni_env["keepass"]
14
14
  cwd = djinni_env["cwd"]
15
- args = cwd.path if (args.nil? || args.empty?)
16
15
 
17
- args = keepass.absolute_path(args, cwd.path)
18
- path, target = args.rsplit("/")
16
+ args = cwd.path if (args.empty?)
17
+ path = keepass.absolute_path(args, cwd.path)
18
+ path, target = path.rsplit("/")
19
19
  new_cwd = keepass.find_group(path)
20
20
 
21
- if (new_cwd)
22
- if (target.empty?)
23
- case djinni_env["djinni_input"]
24
- when "showall"
25
- puts new_cwd.details(0, true)
26
- else
27
- puts new_cwd
28
- end
29
- elsif (new_cwd.has_group?(target))
21
+ if (new_cwd.nil?)
22
+ puts "Group not found"
23
+ return
24
+ end
25
+
26
+ if (target.empty?)
27
+ case djinni_env["djinni_input"]
28
+ when "showall"
29
+ puts new_cwd.details(0, true)
30
+ else
31
+ puts new_cwd
32
+ end
33
+ elsif (new_cwd.has_group?(target))
34
+ case djinni_env["djinni_input"]
35
+ when "showall"
36
+ puts new_cwd.groups[target].details(0, true)
37
+ else
38
+ puts new_cwd.groups[target]
39
+ end
40
+ elsif (new_cwd.has_entry?(target))
41
+ new_cwd.entry_titles.select do |entry|
42
+ target.downcase == entry.downcase
43
+ end.each do |entry|
30
44
  case djinni_env["djinni_input"]
31
45
  when "showall"
32
- puts new_cwd.groups[target].details(0, true)
46
+ puts new_cwd.entries[entry].details(0, true)
33
47
  else
34
- puts new_cwd.groups[target]
35
- end
36
- elsif (new_cwd.has_entry?(target))
37
- new_cwd.entry_titles.select do |entry|
38
- target.downcase == entry.downcase
39
- end.each do |entry|
40
- case djinni_env["djinni_input"]
41
- when "showall"
42
- puts new_cwd.entries[entry].details(0, true)
43
- else
44
- puts new_cwd.entries[entry]
45
- end
48
+ puts new_cwd.entries[entry]
46
49
  end
47
- else
48
- puts "Group/entry \"#{args}\" doesn't exist!"
49
50
  end
50
51
  else
51
- puts "Group/entry \"#{args}\" doesn't exist!"
52
+ puts "Group/Entry not found"
52
53
  end
53
54
  end
54
55
 
55
56
  def tab_complete(input, djinni_env = {})
56
57
  cwd = djinni_env["cwd"]
57
- input, groups, entries = cwd.fuzzy_find(input)
58
- if (groups.empty? && entries.empty?)
59
- return input.gsub(%r{^#{cwd.path}/?}, "")
60
- end
61
-
62
- path, target = input.rsplit("/")
58
+ groups, entries = cwd.fuzzy_find(input)
63
59
 
64
- if (target.empty?)
65
- if ((groups.length == 1) && entries.empty?)
66
- input = "#{path}/#{groups.first}/"
67
- return input.gsub(%r{^#{cwd.path}/?}, "")
68
- elsif (groups.empty? && (entries.length == 1))
69
- input = "#{path}/#{entries.first}"
70
- return input.gsub(%r{^#{cwd.path}/?}, "")
71
- end
72
- puts
73
- groups.each do |group|
74
- puts "#{group}/"
75
- end
76
- puts entries
77
- return input.gsub(%r{^#{cwd.path}/?}, "")
60
+ completions = Hash.new
61
+ groups.each do |group|
62
+ completions[group] = "Group"
78
63
  end
79
-
80
- if (!groups.empty?)
81
- input = "#{path}/#{groups.first}/"
82
- elsif (!entries.empty?)
83
- input = "#{path}/#{entries.first}"
64
+ entries.each do |entry|
65
+ completions[entry] = "Entry"
84
66
  end
85
67
 
86
- return input.gsub(%r{^#{cwd.path}/?}, "")
68
+ append = "/"
69
+ append = "" if (groups.empty?)
70
+
71
+ return [completions, input.rsplit("/")[1], append]
87
72
  end
88
73
 
89
74
  def usage
90
75
  puts "#{aliases.join(", ")} [group|entry]"
91
- puts "\t#{description}."
76
+ puts " #{description}."
92
77
  end
93
78
  end
data/lib/rubeepass.rb CHANGED
@@ -6,7 +6,6 @@ require "pathname"
6
6
  require "rexml/document"
7
7
  require "scoobydoo"
8
8
  require "shellwords"
9
- require "string"
10
9
  require "uri"
11
10
  require "zlib"
12
11
 
@@ -208,7 +207,11 @@ class RubeePass
208
207
 
209
208
  filehash = ""
210
209
  if (@keyfile)
211
- contents = File.readlines(@keyfile).join.fix
210
+ require "string"
211
+ contents = File.readlines(@keyfile).join
212
+ if (contents.length != contents.bytesize)
213
+ contents = contents.unpack("H*").pack("H*")
214
+ end
212
215
  if (contents[0..4] == "<?xml")
213
216
  # XML Key file
214
217
  # My ugly attempt to parse a small XML Key file with a
@@ -352,7 +355,7 @@ class RubeePass
352
355
  data = StringIO.new(
353
356
  cipher.update(encrypted) + cipher.final
354
357
  )
355
- rescue OpenSSL::Cipher::CipherError => e
358
+ rescue OpenSSL::Cipher::CipherError
356
359
  raise Error::InvalidPassword.new
357
360
  end
358
361
 
@@ -455,7 +458,7 @@ class RubeePass
455
458
  return if (@thread.nil?)
456
459
  begin
457
460
  @thread.join
458
- rescue Interrupt => e
461
+ rescue Interrupt
459
462
  puts
460
463
  end
461
464
  end
data/lib/string.rb CHANGED
@@ -1,16 +1,5 @@
1
1
  # Modify String class to allow for rsplit and word wrap
2
2
  class String
3
- def fix
4
- # Fix unicode (I think???)
5
- # Apparently sometimes length and bytesize don't always agree.
6
- # When this happens, there are "invisible" bytes, which I need
7
- # to be "visible". Converting to hex and back fixes this.
8
- if (length != bytesize)
9
- return self.unpack("H*").pack("H*")
10
- end
11
- return self
12
- end
13
-
14
3
  def rsplit(pattern)
15
4
  ret = rpartition(pattern)
16
5
  ret.delete_at(1)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubeepass
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.3
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miles Whittaker
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-21 00:00:00.000000000 Z
11
+ date: 2016-03-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -76,20 +76,20 @@ dependencies:
76
76
  requirements:
77
77
  - - "~>"
78
78
  - !ruby/object:Gem::Version
79
- version: '1.3'
79
+ version: '2.0'
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
- version: 1.3.5
82
+ version: 2.0.0
83
83
  type: :runtime
84
84
  prerelease: false
85
85
  version_requirements: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '1.3'
89
+ version: '2.0'
90
90
  - - ">="
91
91
  - !ruby/object:Gem::Version
92
- version: 1.3.5
92
+ version: 2.0.0
93
93
  - !ruby/object:Gem::Dependency
94
94
  name: json_config
95
95
  requirement: !ruby/object:Gem::Requirement