hunter2 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in hunter2.gemspec
4
+ gemspec
@@ -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
@@ -0,0 +1,7 @@
1
+ require File.expand_path('../lib/hunter2', __FILE__)
2
+
3
+ task_dir = File.expand_path('../task', __FILE__)
4
+
5
+ Dir.glob("#{task_dir}/*.rake").each do |f|
6
+ import(f)
7
+ end
@@ -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
Binary file
File without changes
@@ -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
@@ -0,0 +1,3 @@
1
+ module Hunter2
2
+ Version = '0.0.1'
3
+ end
@@ -0,0 +1,16 @@
1
+ Sequel.migration do
2
+ up do
3
+ create_table :passwords do
4
+ primary_key :id
5
+
6
+ String :key
7
+ String :password
8
+
9
+ Time :created_at
10
+ end
11
+ end
12
+
13
+ down do
14
+ drop_table(:passwords)
15
+ end
16
+ end
@@ -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
@@ -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
@@ -0,0 +1,6 @@
1
+ desc 'Runs all the tests'
2
+ task :test do
3
+ Dir.glob(File.expand_path('../../spec/hunter2/*.rb', __FILE__)).each do |f|
4
+ require(f)
5
+ end
6
+ end
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
+