hunter2 0.0.1
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/Gemfile +4 -0
- data/MANIFEST +16 -0
- data/Rakefile +7 -0
- data/bin/hunter2 +14 -0
- data/database.db +0 -0
- data/lib/database.db +0 -0
- data/lib/hunter2.rb +39 -0
- data/lib/hunter2/command.rb +79 -0
- data/lib/hunter2/model/password.rb +21 -0
- data/lib/hunter2/spec/bacon/color_output.rb +39 -0
- data/lib/hunter2/spec/helper.rb +65 -0
- data/lib/hunter2/version.rb +3 -0
- data/migrations/1313894524_passwords.rb +16 -0
- data/task/build.rake +55 -0
- data/task/db.rake +55 -0
- data/task/test.rake +6 -0
- metadata +147 -0
data/Gemfile
ADDED
data/MANIFEST
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
Gemfile
|
2
|
+
MANIFEST
|
3
|
+
Rakefile
|
4
|
+
bin/hunter2
|
5
|
+
database.db
|
6
|
+
lib/database.db
|
7
|
+
lib/hunter2/command.rb
|
8
|
+
lib/hunter2/model/password.rb
|
9
|
+
lib/hunter2/spec/bacon/color_output.rb
|
10
|
+
lib/hunter2/spec/helper.rb
|
11
|
+
lib/hunter2/version.rb
|
12
|
+
lib/hunter2.rb
|
13
|
+
migrations/1313894524_passwords.rb
|
14
|
+
task/build.rake
|
15
|
+
task/db.rake
|
16
|
+
task/test.rake
|
data/Rakefile
ADDED
data/bin/hunter2
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.expand_path('../../lib/hunter2', __FILE__)
|
4
|
+
|
5
|
+
# Configure the database
|
6
|
+
Hunter2.database = Sequel.connect(
|
7
|
+
:adapter => 'sqlite',
|
8
|
+
:database => '.hunter2.db',
|
9
|
+
:test => false,
|
10
|
+
:encoding => 'utf8'
|
11
|
+
)
|
12
|
+
|
13
|
+
Hunter2.init
|
14
|
+
Shebang.run
|
data/database.db
ADDED
Binary file
|
data/lib/database.db
ADDED
File without changes
|
data/lib/hunter2.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'fast-aes'
|
3
|
+
require 'shebang'
|
4
|
+
require 'sequel'
|
5
|
+
require 'base64'
|
6
|
+
|
7
|
+
['version', 'command'].each do |file|
|
8
|
+
require File.expand_path("../hunter2/#{file}", __FILE__)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Load AES
|
12
|
+
key = '42#3b%c$dxyT,7a5=+5fUI3fa7352&^:'
|
13
|
+
AES = FastAES.new(key)
|
14
|
+
|
15
|
+
# Load all the required Sequel extensions/plugins
|
16
|
+
Sequel.extension(:migration)
|
17
|
+
Sequel::Model.plugin :validation_helpers, :timestamps
|
18
|
+
|
19
|
+
module Hunter2
|
20
|
+
class << self
|
21
|
+
attr_accessor :database
|
22
|
+
attr_accessor :aes
|
23
|
+
|
24
|
+
def init
|
25
|
+
# Ensure we're connected to a database
|
26
|
+
if @database.nil?
|
27
|
+
$stderr.puts('No database connection has been set')
|
28
|
+
exit
|
29
|
+
end
|
30
|
+
|
31
|
+
# Load all the models after the database connection has been established.
|
32
|
+
Dir.glob(
|
33
|
+
File.expand_path('../hunter2/model/*.rb', __FILE__)
|
34
|
+
).each do |f|
|
35
|
+
require(f)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module Hunter2
|
2
|
+
class Command < ::Shebang::Command
|
3
|
+
command :default
|
4
|
+
banner 'Runs an example command.'
|
5
|
+
usage '$ hunter2 [OPTIONS]'
|
6
|
+
|
7
|
+
o :h, :help , 'Shows this help message' , :method => :help
|
8
|
+
o :v, :version , 'Shows the current version', :method => :version
|
9
|
+
|
10
|
+
o :k, :key , 'Key' , :type => String
|
11
|
+
o :p, :password, 'Password', :type => String
|
12
|
+
|
13
|
+
def index
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
def add
|
18
|
+
if option(:p).nil?
|
19
|
+
puts "You need to enter a password."
|
20
|
+
exit
|
21
|
+
end
|
22
|
+
|
23
|
+
# Encrypt password using FastAES
|
24
|
+
encrypted_pass = AES.encrypt(option(:p))
|
25
|
+
|
26
|
+
# Save password and key to database
|
27
|
+
password = Hunter2::Model::Password.create_or_update(
|
28
|
+
:key => option(:k),
|
29
|
+
:password => encrypted_pass
|
30
|
+
)
|
31
|
+
|
32
|
+
puts "Password #{option(:k)} successfully added. Use show -k "+
|
33
|
+
"#{option(:k)} to show your password."
|
34
|
+
end
|
35
|
+
|
36
|
+
def update
|
37
|
+
if option(:p).nil?
|
38
|
+
puts "You need to enter a password."
|
39
|
+
exit
|
40
|
+
end
|
41
|
+
|
42
|
+
# Encrypt password using FastAES
|
43
|
+
encrypted_pass = AES.encrypt(option(:p))
|
44
|
+
|
45
|
+
# Update password
|
46
|
+
password = Hunter2::Model::Password.filter(:key => option(:k)).limit(1)
|
47
|
+
password.update(:password => encrypted_pass)
|
48
|
+
|
49
|
+
puts "Password #{option(:k)} successfully updated."
|
50
|
+
end
|
51
|
+
|
52
|
+
def delete
|
53
|
+
password = Hunter2::Model::Password.filter(:key => option(:k)).limit(1)
|
54
|
+
password.delete
|
55
|
+
|
56
|
+
puts "Password #{option(:k)} successfully deleted."
|
57
|
+
end
|
58
|
+
|
59
|
+
def show
|
60
|
+
# Get encrypted password for this key
|
61
|
+
password = Hunter2::Model::Password.select(:password) \
|
62
|
+
.filter(:key => option(:k)) \
|
63
|
+
.limit(1) \
|
64
|
+
.single_value
|
65
|
+
|
66
|
+
# Decrypt password
|
67
|
+
password = AES.decrypt(password)
|
68
|
+
|
69
|
+
puts "Password for #{option(:key)}: #{password}"
|
70
|
+
end
|
71
|
+
|
72
|
+
protected
|
73
|
+
|
74
|
+
def version
|
75
|
+
puts Hunter2::Version
|
76
|
+
exit
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Hunter2
|
2
|
+
module Model
|
3
|
+
class Password < Sequel::Model
|
4
|
+
plugin :timestamps, :created => :created_at
|
5
|
+
|
6
|
+
def self.create_or_update(params)
|
7
|
+
row = Password[params]
|
8
|
+
|
9
|
+
if row.nil?
|
10
|
+
return create(params)
|
11
|
+
else
|
12
|
+
return row.update(params)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def validate
|
17
|
+
validates_unique(:key)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#:nodoc:
|
2
|
+
module Bacon
|
3
|
+
#:nodoc:
|
4
|
+
module ColorOutput
|
5
|
+
#:nodoc:
|
6
|
+
def handle_specification(name)
|
7
|
+
puts spaces + name
|
8
|
+
yield
|
9
|
+
puts if Counter[:context_depth] == 1
|
10
|
+
end
|
11
|
+
|
12
|
+
#:nodoc:
|
13
|
+
def handle_requirement(description)
|
14
|
+
error = yield
|
15
|
+
|
16
|
+
if !error.empty?
|
17
|
+
puts "#{spaces} \e[31m- #{description} [FAILED]\e[0m"
|
18
|
+
else
|
19
|
+
puts "#{spaces} \e[32m- #{description}\e[0m"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
#:nodoc:
|
24
|
+
def handle_summary
|
25
|
+
print ErrorLog if Backtraces
|
26
|
+
puts "%d specifications (%d requirements), %d failures, %d errors" %
|
27
|
+
Counter.values_at(:specifications, :requirements, :failed, :errors)
|
28
|
+
end
|
29
|
+
|
30
|
+
#:nodoc:
|
31
|
+
def spaces
|
32
|
+
if Counter[:context_depth] === 0
|
33
|
+
Counter[:context_depth] = 1
|
34
|
+
end
|
35
|
+
|
36
|
+
return ' ' * (Counter[:context_depth] - 1)
|
37
|
+
end
|
38
|
+
end # ColorOutput
|
39
|
+
end # Bacon
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'bacon'
|
2
|
+
require 'stringio'
|
3
|
+
require File.expand_path('../bacon/color_output', __FILE__)
|
4
|
+
|
5
|
+
Bacon.extend(Bacon::ColorOutput)
|
6
|
+
Bacon.summary_on_exit
|
7
|
+
|
8
|
+
##
|
9
|
+
# Runs the block in a new thread and redirects $stdout and $stderr. The output
|
10
|
+
# normally stored in these variables is stored in an instance of StringIO which
|
11
|
+
# is returned as a hash.
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
# out = catch_output do
|
15
|
+
# puts 'hello'
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# puts out # => {:stdout => "hello\n", :stderr => ""}
|
19
|
+
#
|
20
|
+
# @author Yorick Peterse
|
21
|
+
# @return [Hash]
|
22
|
+
#
|
23
|
+
def catch_output
|
24
|
+
data = {
|
25
|
+
:stdout => nil,
|
26
|
+
:stderr => nil
|
27
|
+
}
|
28
|
+
|
29
|
+
Thread.new do
|
30
|
+
$stdout, $stderr = StringIO.new, StringIO.new
|
31
|
+
|
32
|
+
yield
|
33
|
+
|
34
|
+
$stdout.rewind
|
35
|
+
$stderr.rewind
|
36
|
+
|
37
|
+
data[:stdout], data[:stderr] = $stdout.read, $stderr.read
|
38
|
+
|
39
|
+
$stdout, $stderr = STDOUT, STDERR
|
40
|
+
end.join
|
41
|
+
|
42
|
+
return data
|
43
|
+
end
|
44
|
+
|
45
|
+
##
|
46
|
+
# Allows developers to create stubbed objects similar to Mocha's stub() method.
|
47
|
+
#
|
48
|
+
# @example
|
49
|
+
# obj = stub(:language => 'Ruby')
|
50
|
+
# puts obj.language # => "Ruby"
|
51
|
+
#
|
52
|
+
# @author Yorick Peterse
|
53
|
+
# @param [Hash] attributes A hash containing all the attributes to set and
|
54
|
+
# their values.
|
55
|
+
# @return [Class]
|
56
|
+
#
|
57
|
+
def stub(attributes)
|
58
|
+
obj = Struct.new(*attributes.keys).new
|
59
|
+
|
60
|
+
attributes.each do |k, v|
|
61
|
+
obj.send("#{k}=", v)
|
62
|
+
end
|
63
|
+
|
64
|
+
return obj
|
65
|
+
end
|
data/task/build.rake
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'find'
|
2
|
+
|
3
|
+
namespace :build do
|
4
|
+
|
5
|
+
desc 'Builds the documentation using YARD'
|
6
|
+
task :doc do
|
7
|
+
gem_path = File.expand_path('../../', __FILE__)
|
8
|
+
command = "yard doc #{gem_path}/lib -m markdown -M rdiscount -o #{gem_path}/doc "
|
9
|
+
command += "-r #{gem_path}/README.md --private --protected "
|
10
|
+
command += "--files #{gem_path}/LICENSE"
|
11
|
+
|
12
|
+
sh(command)
|
13
|
+
end
|
14
|
+
|
15
|
+
desc 'Builds a new Gem and installs it'
|
16
|
+
task :gem do
|
17
|
+
gem_path = File.expand_path('../../', __FILE__)
|
18
|
+
|
19
|
+
# Build and install the gem
|
20
|
+
sh("gem build #{gem_path}/hunter2.gemspec")
|
21
|
+
sh("mv #{gem_path}/hunter2-#{Hunter2::Version}.gem #{gem_path}/pkg")
|
22
|
+
sh("gem install #{gem_path}/pkg/hunter2-#{Hunter2::Version}.gem")
|
23
|
+
end
|
24
|
+
|
25
|
+
desc 'Builds the MANIFEST file'
|
26
|
+
task :manifest do
|
27
|
+
gem_path = File.expand_path('../../', __FILE__)
|
28
|
+
ignore_exts = ['.gem', '.gemspec', '.swp']
|
29
|
+
ignore_files = ['.DS_Store', '.gitignore']
|
30
|
+
ignore_dirs = ['.git', '.yardoc', 'spec', 'pkg', 'doc']
|
31
|
+
files = ''
|
32
|
+
|
33
|
+
Find.find(gem_path) do |f|
|
34
|
+
f[gem_path] = ''
|
35
|
+
f.gsub!(/^\//, '')
|
36
|
+
|
37
|
+
# Ignore directories
|
38
|
+
if !File.directory?(f) and !ignore_exts.include?(File.extname(f)) and !ignore_files.include?(File.basename(f))
|
39
|
+
files += "#{f}\n"
|
40
|
+
else
|
41
|
+
Find.prune if ignore_dirs.include?(f)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Time to write the MANIFEST file
|
46
|
+
begin
|
47
|
+
handle = File.open 'MANIFEST', 'w'
|
48
|
+
handle.write files.strip
|
49
|
+
puts "The MANIFEST file has been updated."
|
50
|
+
rescue
|
51
|
+
abort "The MANIFEST file could not be written."
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
data/task/db.rake
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
namespace :db do
|
2
|
+
desc 'Migrates the database to the most recent or the specified version'
|
3
|
+
task :migrate, :version do |task, args|
|
4
|
+
if !args[:version]
|
5
|
+
version = nil
|
6
|
+
else
|
7
|
+
version = args[:version].to_i
|
8
|
+
end
|
9
|
+
|
10
|
+
Sequel::Migrator.run(
|
11
|
+
Hunter2.database,
|
12
|
+
File.expand_path('../../migrations', __FILE__),
|
13
|
+
:target => version
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
desc 'Generates a new migration'
|
18
|
+
task :migration, :name do |task, args|
|
19
|
+
if !args[:name]
|
20
|
+
abort 'You need to specify a name for the migration'
|
21
|
+
end
|
22
|
+
|
23
|
+
# Generate the name of the migration
|
24
|
+
path = File.join(
|
25
|
+
File.expand_path('../../migrations', __FILE__),
|
26
|
+
"#{Time.new.to_i}_#{args[:name]}.rb"
|
27
|
+
)
|
28
|
+
|
29
|
+
if File.exist?(path)
|
30
|
+
abort "The migration #{path} already exists"
|
31
|
+
end
|
32
|
+
|
33
|
+
template = <<-TEMPLATE
|
34
|
+
Sequel.migration do
|
35
|
+
up do
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
down do
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
TEMPLATE
|
44
|
+
|
45
|
+
# Write the migration
|
46
|
+
File.open(path, 'w') do |handle|
|
47
|
+
begin
|
48
|
+
handle.write(template.strip)
|
49
|
+
puts "Saved the migration in #{path}"
|
50
|
+
rescue => e
|
51
|
+
abort "Failed to write the migration: #{e.message}"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end # namespace :db
|
data/task/test.rake
ADDED
metadata
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hunter2
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Abdelrahman Mahmoud
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-08-03 00:00:00 +02:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: sequel
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ~>
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 3.26.0
|
25
|
+
type: :runtime
|
26
|
+
version_requirements: *id001
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: fast-aes
|
29
|
+
prerelease: false
|
30
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
33
|
+
- - ~>
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: 0.1.1
|
36
|
+
type: :runtime
|
37
|
+
version_requirements: *id002
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: bcrypt-ruby
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ~>
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 2.1.4
|
47
|
+
type: :runtime
|
48
|
+
version_requirements: *id003
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: rake
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ~>
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: 0.8.7
|
58
|
+
type: :development
|
59
|
+
version_requirements: *id004
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
name: rspec
|
62
|
+
prerelease: false
|
63
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 2.6.0
|
69
|
+
type: :development
|
70
|
+
version_requirements: *id005
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: yard
|
73
|
+
prerelease: false
|
74
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ~>
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: 0.7.1
|
80
|
+
type: :development
|
81
|
+
version_requirements: *id006
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
name: rdiscount
|
84
|
+
prerelease: false
|
85
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ~>
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: 1.6.8
|
91
|
+
type: :development
|
92
|
+
version_requirements: *id007
|
93
|
+
description: A CLI-based password manager in Ruby.
|
94
|
+
email: abdel@aplusm.me
|
95
|
+
executables:
|
96
|
+
- hunter2
|
97
|
+
extensions: []
|
98
|
+
|
99
|
+
extra_rdoc_files: []
|
100
|
+
|
101
|
+
files:
|
102
|
+
- Gemfile
|
103
|
+
- MANIFEST
|
104
|
+
- Rakefile
|
105
|
+
- bin/hunter2
|
106
|
+
- database.db
|
107
|
+
- lib/database.db
|
108
|
+
- lib/hunter2/command.rb
|
109
|
+
- lib/hunter2/model/password.rb
|
110
|
+
- lib/hunter2/spec/bacon/color_output.rb
|
111
|
+
- lib/hunter2/spec/helper.rb
|
112
|
+
- lib/hunter2/version.rb
|
113
|
+
- lib/hunter2.rb
|
114
|
+
- migrations/1313894524_passwords.rb
|
115
|
+
- task/build.rake
|
116
|
+
- task/db.rake
|
117
|
+
- task/test.rake
|
118
|
+
has_rdoc: true
|
119
|
+
homepage: https://github.com/abdelm/hunter2
|
120
|
+
licenses: []
|
121
|
+
|
122
|
+
post_install_message:
|
123
|
+
rdoc_options: []
|
124
|
+
|
125
|
+
require_paths:
|
126
|
+
- lib
|
127
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
128
|
+
none: false
|
129
|
+
requirements:
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: "0"
|
133
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
134
|
+
none: false
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: "0"
|
139
|
+
requirements: []
|
140
|
+
|
141
|
+
rubyforge_project:
|
142
|
+
rubygems_version: 1.6.2
|
143
|
+
signing_key:
|
144
|
+
specification_version: 3
|
145
|
+
summary: Kick-ass CLI-based password manager.
|
146
|
+
test_files: []
|
147
|
+
|