one_pass 0.1.0 → 0.3.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 +4 -4
- data/.gitignore +1 -0
- data/Gemfile.lock +3 -5
- data/README.markdown +5 -0
- data/exe/one-pass +2 -0
- data/lib/OnePass/application.rb +14 -79
- data/lib/OnePass/cli.rb +14 -2
- data/lib/OnePass/op_vault.rb +4 -0
- data/lib/OnePass/password.rb +80 -0
- data/lib/OnePass/version.rb +1 -1
- data/one_pass.gemspec +1 -1
- metadata +9 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0cc1151fd6e205e25446f3ccc96ea2ade11ae65f
|
4
|
+
data.tar.gz: 38a4224636c6cdd21c05bb4e468b95326ebbe271
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4b8ecca56031bbfc20f1f59be2386f52ba18cf57cf9067738498b7fccf1f0fda6c68071719f2d4c9b3b4efada10f137bd08f04aead0948ba91400d3fb1522c27
|
7
|
+
data.tar.gz: c24eed919126dae1d4dd16f763d29690f2a4cd2dd5d2e1e87b1a10ac6202709f9e5a2be3c1bc3a4bee8b8fb5922c31cdbe562adc66a20e1e158de632f5c40cc7
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,19 +1,16 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
one_pass (0.
|
5
|
-
dispel (~> 0.0)
|
4
|
+
one_pass (0.3.0)
|
6
5
|
thor (~> 0.19)
|
6
|
+
ttyname (~> 1.0)
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
11
|
bump (0.5.3)
|
12
12
|
coderay (1.1.1)
|
13
|
-
curses (1.0.2)
|
14
13
|
diff-lcs (1.2.5)
|
15
|
-
dispel (0.0.7)
|
16
|
-
curses
|
17
14
|
method_source (0.8.2)
|
18
15
|
pry (0.10.3)
|
19
16
|
coderay (~> 1.1.0)
|
@@ -35,6 +32,7 @@ GEM
|
|
35
32
|
rspec-support (3.4.1)
|
36
33
|
slop (3.6.0)
|
37
34
|
thor (0.19.1)
|
35
|
+
ttyname (1.0.0)
|
38
36
|
|
39
37
|
PLATFORMS
|
40
38
|
ruby
|
data/README.markdown
CHANGED
@@ -26,3 +26,8 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/sethvo
|
|
26
26
|
## License
|
27
27
|
|
28
28
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
29
|
+
|
30
|
+
## Todo
|
31
|
+
|
32
|
+
* [ ] Check for prerequisite external applications before calling them (pinentry, pbcopy)
|
33
|
+
* [ ] Detect OS to use appropriate clipboard utility
|
data/exe/one-pass
CHANGED
data/lib/OnePass/application.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'dispel'
|
2
|
-
|
3
1
|
module OnePass
|
4
2
|
# OnePass Application
|
5
3
|
class Application
|
@@ -9,85 +7,22 @@ module OnePass
|
|
9
7
|
@vault_path = get_vault vault_path
|
10
8
|
@vault = OpVault.new @vault_path
|
11
9
|
|
12
|
-
|
13
|
-
@
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
mode: :password
|
25
|
-
}
|
26
|
-
screen.draw *draw_password_box(accumulator.length, config)
|
27
|
-
|
28
|
-
Dispel::Keyboard.output do |key|
|
29
|
-
case key
|
30
|
-
when :enter
|
31
|
-
case config[:mode]
|
32
|
-
when :cancel
|
33
|
-
raise 'Cancel'
|
34
|
-
else
|
35
|
-
break
|
36
|
-
end
|
37
|
-
when :backspace
|
38
|
-
accumulator.pop
|
39
|
-
when :down
|
40
|
-
config[:mode] = config[:mode] == :password ? :ok : config[:mode]
|
41
|
-
when :up
|
42
|
-
config[:mode] = :password
|
43
|
-
when :left
|
44
|
-
config[:mode] = config[:mode] == :password ? config[:mode] : :ok
|
45
|
-
when :right
|
46
|
-
config[:mode] = config[:mode] == :password ? config[:mode] : :cancel
|
47
|
-
else
|
48
|
-
accumulator.push key if config[:mode] == :password
|
49
|
-
end
|
50
|
-
screen.draw *draw_password_box(accumulator.length, config)
|
10
|
+
error_message = nil
|
11
|
+
prompter = OnePass::Password.new(vault_path: @vault_path)
|
12
|
+
loop do
|
13
|
+
password = prompter.prompt error_message
|
14
|
+
exit if password.nil? # cancelled
|
15
|
+
begin
|
16
|
+
@vault.unlock password
|
17
|
+
@vault.load_items
|
18
|
+
break
|
19
|
+
rescue => error
|
20
|
+
error_message = error.message
|
21
|
+
next
|
51
22
|
end
|
52
23
|
end
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
def draw_password_box(pw_length, config)
|
57
|
-
message = 'Please enter your 1Password master password for the following vault:'
|
58
|
-
min_width = [message, @vault_path].max_by(&:length).length
|
59
|
-
prefix = 'Master Password: '
|
60
|
-
|
61
|
-
offset_left = (config[:width] - (min_width + 4)) / 2
|
62
|
-
offset_top = (config[:height] - 8) / 2
|
63
|
-
left = ' ' * offset_left
|
64
|
-
third = min_width / 3
|
65
|
-
|
66
|
-
password_string = ("*" * pw_length).ljust(min_width - prefix.length, '_')
|
67
|
-
buttons = '<OK>'.center(third) + ' ' * (min_width - (third * 2)) + '<Cancel>'.center(third)
|
68
|
-
|
69
|
-
box = ("\n" * offset_top)
|
70
|
-
box += "#{left}┏#{'━' * (min_width + 2)}┓\n"
|
71
|
-
box += "#{left}┃ #{message.ljust(min_width)} ┃\n"
|
72
|
-
box += "#{left}┃ #{@vault_path.ljust(min_width)} ┃\n"
|
73
|
-
box += "#{left}┃ #{' ' * min_width} ┃\n"
|
74
|
-
box += "#{left}┃ #{prefix}#{password_string} ┃\n"
|
75
|
-
box += "#{left}┃#{' ' * (min_width + 2)}┃\n"
|
76
|
-
box += "#{left}┃ #{buttons} ┃\n"
|
77
|
-
box += "#{left}┗#{'━' * (min_width + 2)}┛\n"
|
78
|
-
|
79
|
-
cursor_top = offset_top + (config[:mode] == :password ? 4 : 6)
|
80
|
-
cursor_left = offset_left
|
81
|
-
case config[:mode]
|
82
|
-
when :ok
|
83
|
-
cursor_left += third / 2
|
84
|
-
when :cancel
|
85
|
-
cursor_left += min_width - third + third / 2 - 2
|
86
|
-
else
|
87
|
-
cursor_left += prefix.length + pw_length + 2
|
88
|
-
end
|
89
|
-
|
90
|
-
[box, config[:map], [cursor_top, cursor_left]]
|
24
|
+
ensure
|
25
|
+
prompter.done
|
91
26
|
end
|
92
27
|
|
93
28
|
def get_vault(vault_path = nil)
|
data/lib/OnePass/cli.rb
CHANGED
@@ -2,14 +2,21 @@ require 'io/console'
|
|
2
2
|
require 'thor'
|
3
3
|
|
4
4
|
require 'OnePass/application'
|
5
|
+
require 'OnePass/password'
|
5
6
|
|
6
7
|
module OnePass
|
7
8
|
# OnePass CLI
|
8
9
|
class CLI < Thor
|
9
10
|
SHOW_OPTIONS = %w( all username password url uuid title )
|
10
11
|
|
12
|
+
map %w[--version -v] => :__version
|
13
|
+
desc "--version, -v", "Print the current version"
|
14
|
+
def __version
|
15
|
+
puts "#{File.basename $0} version #{OnePass::VERSION}"
|
16
|
+
end
|
17
|
+
|
11
18
|
desc 'login', 'Save a 1Password vault and verify password'
|
12
|
-
option :vault, aliases: '-v', type: :string, banner: 'Specify a vault path'
|
19
|
+
option :vault, aliases: '-v', type: :string, banner: 'Specify a vault path', required: true
|
13
20
|
def login
|
14
21
|
OnePass::Application.save options.vault
|
15
22
|
end
|
@@ -39,7 +46,12 @@ module OnePass
|
|
39
46
|
app = OnePass::Application.new
|
40
47
|
reply_type = type.keys.first.to_sym
|
41
48
|
reply = app.show name, reply_type
|
42
|
-
|
49
|
+
if options.clip
|
50
|
+
IO.popen('pbcopy', 'w') { |f| f << (reply_type == :all ? JSON.generate(reply) : reply) }
|
51
|
+
else
|
52
|
+
print reply_type == :all ? JSON.pretty_generate(reply) : reply
|
53
|
+
puts if $stdout.isatty
|
54
|
+
end
|
43
55
|
end
|
44
56
|
|
45
57
|
desc 'search QUERY', 'Perform fuzzy search for items in your vault, shows uuid, title and username'
|
data/lib/OnePass/op_vault.rb
CHANGED
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'ttyname'
|
2
|
+
|
3
|
+
module OnePass
|
4
|
+
# Fork out to `pinentry` for password
|
5
|
+
class Password
|
6
|
+
DESCRIPTION = 'Please enter your 1Password master password for the following vault:'
|
7
|
+
DEFAULT = {
|
8
|
+
title: '1Password CLI',
|
9
|
+
prompt: 'Master Password: '
|
10
|
+
}
|
11
|
+
|
12
|
+
def initialize(opts = {})
|
13
|
+
@config = OpenStruct.new DEFAULT.merge(opts)
|
14
|
+
@config.description ||= "#{DESCRIPTION}%0a#{@config.vault_path}" if @config.vault_path
|
15
|
+
end
|
16
|
+
|
17
|
+
def prompt(error_message = nil)
|
18
|
+
@config.error = error_message
|
19
|
+
@pipe = IO.popen 'pinentry', 'r+'
|
20
|
+
check
|
21
|
+
send_settings
|
22
|
+
get_password
|
23
|
+
@password
|
24
|
+
end
|
25
|
+
|
26
|
+
def done
|
27
|
+
send 'BYE'
|
28
|
+
@pipe.close
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def send_settings
|
34
|
+
command 'SETTITLE', @config.title
|
35
|
+
command 'SETPROMPT', @config.prompt
|
36
|
+
command 'SETERROR', @config.error if @config.error
|
37
|
+
command 'SETDESC', @config.description
|
38
|
+
|
39
|
+
option 'ttytype', ENV['TERM']
|
40
|
+
option 'ttyname', $stdin.ttyname
|
41
|
+
option 'display', ENV['DISPLAY']
|
42
|
+
end
|
43
|
+
|
44
|
+
def get_password
|
45
|
+
@password = ''
|
46
|
+
send 'GETPIN'
|
47
|
+
while true
|
48
|
+
case response = @pipe.gets
|
49
|
+
when /^D .*/
|
50
|
+
@password = response[2..-1].chomp
|
51
|
+
when /^OK/
|
52
|
+
break
|
53
|
+
else
|
54
|
+
@password = nil
|
55
|
+
break
|
56
|
+
end
|
57
|
+
end
|
58
|
+
rescue Interrupt
|
59
|
+
@password = nil
|
60
|
+
end
|
61
|
+
|
62
|
+
def command(command, option = nil)
|
63
|
+
send command, option
|
64
|
+
check
|
65
|
+
end
|
66
|
+
|
67
|
+
def option(name, value)
|
68
|
+
command 'OPTION', "#{name}=#{value}"
|
69
|
+
end
|
70
|
+
|
71
|
+
def send(command, option = nil)
|
72
|
+
@pipe.puts "#{command}#{option ? ' ' + option : ''}"
|
73
|
+
end
|
74
|
+
|
75
|
+
def check
|
76
|
+
response = @pipe.gets
|
77
|
+
raise 'bad response' unless response.start_with? 'OK'
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
data/lib/OnePass/version.rb
CHANGED
data/one_pass.gemspec
CHANGED
@@ -27,8 +27,8 @@ Gem::Specification.new do |spec|
|
|
27
27
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
28
28
|
spec.require_paths = ["lib"]
|
29
29
|
|
30
|
-
spec.add_runtime_dependency "dispel", "~> 0.0"
|
31
30
|
spec.add_runtime_dependency "thor", "~> 0.19"
|
31
|
+
spec.add_runtime_dependency "ttyname", "~> 1.0"
|
32
32
|
|
33
33
|
spec.add_development_dependency "bundler", "~> 1.11"
|
34
34
|
spec.add_development_dependency "rake", "~> 10.0"
|
metadata
CHANGED
@@ -1,43 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: one_pass
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Seth Voltz
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-04-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: thor
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0.
|
19
|
+
version: '0.19'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '0.
|
26
|
+
version: '0.19'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: ttyname
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0
|
33
|
+
version: '1.0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '0
|
40
|
+
version: '1.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: bundler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -120,6 +120,7 @@ files:
|
|
120
120
|
- lib/OnePass/application.rb
|
121
121
|
- lib/OnePass/cli.rb
|
122
122
|
- lib/OnePass/op_vault.rb
|
123
|
+
- lib/OnePass/password.rb
|
123
124
|
- lib/OnePass/version.rb
|
124
125
|
- one_pass.gemspec
|
125
126
|
homepage: https://sethvoltz.github.com/one_pass
|