passman 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bda4662265b49027fdbcd554dec1e3d3647a2ace
4
+ data.tar.gz: 34836b929208a72a53171d148eb72ce1713793b2
5
+ SHA512:
6
+ metadata.gz: 039799e9ba6eadd3039554d51796129b66240011b74c25ca9f59ce892e42c73d51140dad085070198615e66a556f8842d986b6c1cb9e594ab64e3ff470543506
7
+ data.tar.gz: 8dda4311d9e2afb3b405672caebc6332727963658c777883605739b3684e158790b4ff4e3fa6274e2ad8a91dbd7e1b79c81d04b261593e3973e1a57187687893
data/.gitignore ADDED
@@ -0,0 +1,73 @@
1
+
2
+ # Created by https://www.gitignore.io/api/ruby,osx
3
+
4
+ *.log
5
+ .byebug_history
6
+ /spec/test_files
7
+ *.test
8
+ *.json
9
+
10
+ ### Ruby ###
11
+ *.gem
12
+ *.rbc
13
+ /.config
14
+ /coverage/
15
+ /InstalledFiles
16
+ /pkg/
17
+ /spec/reports/
18
+ /spec/examples.txt
19
+ /test/tmp/
20
+ /test/version_tmp/
21
+ /tmp/
22
+
23
+ ## Specific to RubyMotion:
24
+ .dat*
25
+ .repl_history
26
+ build/
27
+
28
+ ## Documentation cache and generated files:
29
+ /.yardoc/
30
+ /_yardoc/
31
+ /doc/
32
+ /rdoc/
33
+
34
+ ## Environment normalisation:
35
+ /.bundle/
36
+ /vendor/bundle
37
+ /lib/bundler/man/
38
+
39
+ # for a library or gem, you might want to ignore these files since the code is
40
+ # intended to run in multiple environments; otherwise, check them in:
41
+ Gemfile.lock
42
+ .ruby-version
43
+ .ruby-gemset
44
+
45
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
46
+ .rvmrc
47
+
48
+ ### OSX ###
49
+ .DS_Store
50
+ .AppleDouble
51
+ .LSOverride
52
+
53
+ # Icon must end with two \r
54
+ Icon
55
+
56
+ # Thumbnails
57
+ ._*
58
+
59
+ # Files that might appear in the root of a volume
60
+ .DocumentRevisions-V100
61
+ .fseventsd
62
+ .Spotlight-V100
63
+ .TemporaryItems
64
+ .Trashes
65
+ .VolumeIcon.icns
66
+
67
+ # Directories potentially created on remote AFP share
68
+ .AppleDB
69
+ .AppleDesktop
70
+ Network Trash Folder
71
+ Temporary Items
72
+ .apdisk
73
+
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/.rubocop.yml ADDED
@@ -0,0 +1,13 @@
1
+ AllCops:
2
+ Exclude:
3
+ - passman.gemspec
4
+ - bin/passman
5
+
6
+ Documentation:
7
+ Enabled: false
8
+
9
+ LineLength:
10
+ Max: 99
11
+
12
+ FrozenStringLiteralComment:
13
+ Enabled: false
data/.travis.yml ADDED
@@ -0,0 +1,35 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1
6
+ - 2.2
7
+ - 2.2.4
8
+ - 2.3.0
9
+
10
+ install:
11
+ - gem install bundler
12
+ - bundle install --retry=3
13
+
14
+ script:
15
+ - bundle exec rspec
16
+ - bundle exec rubocop -R --format simple
17
+
18
+ addons:
19
+ code_climate:
20
+ repo_token: 05608bdc27971472c5009272a2b4df770c9ea5c67e139e4225c37e76b01a3118
21
+
22
+ os:
23
+ - linux
24
+ - osx
25
+
26
+ matrix:
27
+ exclude:
28
+ - rvm: 1.9.3
29
+ os: osx
30
+ - rvm: 2.2
31
+ os: osx
32
+ - rvm: 2.2.4
33
+ os: osx
34
+ - rvm: 2.3.0
35
+ os: osx
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in crf.gemspec
4
+ gemspec
5
+
6
+ gem 'rake', '~> 11.1'
7
+ gem 'rspec', '~> 3.4'
8
+
9
+ group :test do
10
+ gem 'codeclimate-test-reporter', require: false
11
+ end
data/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Alejandro Bezdjian, aka alebian
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,38 @@
1
+ # PassMan - Password Manager
2
+ [![Gem Version](https://badge.fury.io/rb/passman.svg)]()
3
+ [![Dependency Status](https://gemnasium.com/badges/github.com/alebian/passman.svg)](https://gemnasium.com/github.com/alebian/passman)
4
+ [![Build Status](https://travis-ci.org/alebian/passman.svg)](https://travis-ci.org/alebian/passman)
5
+ [![Code Climate](https://codeclimate.com/github/alebian/passman/badges/gpa.svg)](https://codeclimate.com/github/alebian/passman)
6
+ [![Test Coverage](https://codeclimate.com/github/alebian/passman/badges/coverage.svg)](https://codeclimate.com/github/alebian/passman/coverage)
7
+ [![Inline docs](http://inch-ci.org/github/alebian/passman.svg)](http://inch-ci.org/github/alebian/passman)
8
+
9
+ PassMan is a command line application that stores your passwords encripted with a symmetric-key algorithm. It also let's you save more information about your accounts such as recovery information and more.
10
+
11
+ ## Installation
12
+
13
+ Run this in your terminal:
14
+
15
+ $ gem install passman
16
+
17
+ ## Usage
18
+
19
+ After installing the gem, you can use it in your command line:
20
+
21
+ ```
22
+ passman
23
+ ```
24
+
25
+ ```ruby
26
+
27
+ ```
28
+
29
+
30
+ ## Contributing
31
+
32
+ 1. Fork it
33
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
34
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
35
+ 4. Run rubocop lint (`rubocop -R --format simple`)
36
+ 5. Run rspec tests (`bundle exec rspec`)
37
+ 6. Push your branch (`git push origin my-new-feature`)
38
+ 7. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
data/bin/passman ADDED
@@ -0,0 +1,119 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'passman'
4
+ require 'optparse'
5
+ require 'colorize'
6
+ require 'io/console'
7
+
8
+ options = {}
9
+
10
+ begin
11
+
12
+ parser = OptionParser.new do |opts|
13
+ opts.banner = 'Usage: passman [-a account] [-p password] [-f file] [-r file] [-g number] [-v] [-h]'
14
+
15
+ opts.on('-a', '--add STR', 'Account to add a password') do |account|
16
+ options[:account] = account
17
+ end
18
+
19
+ opts.on('-u', '--username STR', 'Username of the account') do |username|
20
+ options[:username] = username
21
+ end
22
+
23
+ opts.on('-p', '--password STR', 'Password to add') do |password|
24
+ options[:password] = password
25
+ options[:generate] = false
26
+ end
27
+
28
+ opts.on('-f', '--file STR', 'Path to the file where passwords will be saved') do |file|
29
+ raise ArgumentError, 'File not found' unless File.exist?(file)
30
+ options[:file] = file
31
+ end
32
+
33
+ opts.on('-r', '--retreive STR', 'Account to retreive') do |account|
34
+ options[:retreive] = account
35
+ end
36
+
37
+ opts.on('-d', '--delete STR', 'Account to remove') do |account|
38
+ options[:remove] = account
39
+ end
40
+
41
+ opts.on('-g', '--generate [N]', Integer, 'Generates a new random password of N characters, or default if N is not provided') do |length|
42
+ options[:length] = length
43
+ options[:generate] = true
44
+ end
45
+
46
+ opts.on('-l', '--list', 'List your saved keys') do |length|
47
+ options[:list] = length
48
+ end
49
+
50
+ opts.on('-v', '--version', 'Displays version') do
51
+ puts "PassMan Version: #{Passman::VERSION}"
52
+ exit
53
+ end
54
+
55
+ opts.on('-h', '--help', 'Displays help') do
56
+ puts opts
57
+ exit
58
+ end
59
+ end
60
+
61
+ parser.parse!
62
+
63
+ if options[:account]
64
+
65
+ raise ArgumentError, 'No username provided.' unless options[:username]
66
+ password = ''
67
+ if options[:password]
68
+ password = options[:password]
69
+ else
70
+ password = Passman.generate_password(options[:length])
71
+ end
72
+
73
+ if Passman.get(options[:account], options[:file])
74
+ print 'There is a username already stored. Do you want to overwrite it? [Y/n] '
75
+ overwrite = gets
76
+ exit unless overwrite == 'Y'
77
+ puts ''
78
+ end
79
+
80
+ print 'Insert your symmetric-key: '
81
+ key = STDIN.noecho(&:gets)
82
+ puts ''
83
+ Passman.add(options[:account], options[:username], Passman::Crypto.encrypt(password, key.chomp), options[:file])
84
+
85
+ puts 'Password successfully added'.colorize(:green)
86
+
87
+ elsif options[:delete]
88
+
89
+ Passman.delete(options[:delete], options[:file])
90
+ puts 'Password deleted'.colorize(:green)
91
+
92
+ elsif options[:list]
93
+
94
+ Passman.database(options[:file]).each do |account, data|
95
+ puts account.colorize(:yellow) + ' -> ' + data['username']
96
+ end
97
+
98
+ elsif options[:generate]
99
+
100
+ puts Passman.generate_password(options[:length])
101
+
102
+ elsif options[:retreive]
103
+
104
+ account = Passman.get(options[:retreive], options[:file])
105
+ print 'Insert your symmetric-key: '
106
+ key = STDIN.noecho(&:gets)
107
+ puts ''
108
+ puts "Account: #{options[:retreive]}, Username: #{account['username']}, Password: #{Passman::Crypto.decrypt(account['password'], key)}"
109
+
110
+ else
111
+
112
+ raise ArgumentError, 'No account provided.'
113
+
114
+ end
115
+
116
+ rescue SystemExit => exception
117
+ rescue Exception => exception
118
+ puts exception.message.colorize(:red)
119
+ end
@@ -0,0 +1,30 @@
1
+ require 'openssl'
2
+ require 'base64'
3
+
4
+ module Passman
5
+ class Crypto
6
+ class << self
7
+ def encrypt(password, key)
8
+ cipher = new_cipher
9
+ cipher.encrypt
10
+ cipher.key = key
11
+ encrypted_password = cipher.update(password) + cipher.final
12
+ Base64.encode64(encrypted_password)
13
+ end
14
+
15
+ def decrypt(encrypted_password, key)
16
+ cipher = new_cipher
17
+ cipher.decrypt
18
+ cipher.key = key
19
+ decrypted_password = cipher.update(Base64.decode64(encrypted_password))
20
+ decrypted_password << cipher.final
21
+ end
22
+
23
+ private
24
+
25
+ def new_cipher
26
+ OpenSSL::Cipher::AES.new(256, 'CBC')
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,9 @@
1
+ require 'securerandom'
2
+
3
+ module Passman
4
+ class PasswordGenerator
5
+ def self.generate(length)
6
+ SecureRandom.hex(length)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ module Passman
2
+ VERSION = '0.0.1'.freeze
3
+ end
data/lib/passman.rb ADDED
@@ -0,0 +1,44 @@
1
+ require_relative 'passman/crypto'
2
+ require 'passman/password_generator'
3
+ require 'passman/version'
4
+ require 'json'
5
+
6
+ module Passman
7
+ DEFAULT_FILE = 'passman.json'.freeze
8
+
9
+ def self.generate_password(length)
10
+ Passman::PasswordGenerator.generate(length / 2)
11
+ end
12
+
13
+ def self.add(account, username, encrypted_password, file = nil)
14
+ path = DEFAULT_FILE if file.nil?
15
+ db = database(path)
16
+ db[account.to_s] = { username: username, password: encrypted_password }
17
+ write_database(db, path)
18
+ end
19
+
20
+ def self.delete(account, file = nil)
21
+ path = DEFAULT_FILE if file.nil?
22
+ db = database(path)
23
+ db.delete(account.to_s)
24
+ write_database(db, path)
25
+ end
26
+
27
+ def self.get(account, key, file = nil)
28
+ path = DEFAULT_FILE if file.nil?
29
+ db = database(path)
30
+ db[account.to_s]
31
+ end
32
+
33
+ def self.database(file)
34
+ return JSON.parse(File.read(file)) if File.exist?(file)
35
+ {}
36
+ end
37
+
38
+ def self.write_database(data, path)
39
+ File.delete(path) if File.exist?(path)
40
+ file = File.open(path, 'w+')
41
+ file.write(JSON.generate(data))
42
+ file.close
43
+ end
44
+ end
data/passman.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'passman/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'passman'
8
+ spec.version = Passman::VERSION
9
+ spec.authors = ['Alejandro Bezdjian']
10
+ spec.email = 'alebezdjian@gmail.com'
11
+ spec.date = Date.today
12
+ spec.summary = 'Password manager.'
13
+ spec.description = "PassMan is a password manager that stores your passwords encrypted, let's you retreive them and create new ones."
14
+ spec.platform = Gem::Platform::RUBY
15
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec)/}) }
16
+ spec.require_paths = ['lib']
17
+ spec.homepage = 'https://github.com/alebian/passman'
18
+ spec.license = 'MIT'
19
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
+ spec.test_files = spec.files.grep(%r{^(test|spec)/})
21
+
22
+ spec.add_dependency 'colorize', '~> 0.7', '>= 0.7.5'
23
+
24
+ spec.add_development_dependency 'bundler', '>= 1.3.0', '< 2.0'
25
+ spec.add_development_dependency 'byebug' if RUBY_VERSION >= '2.0.0'
26
+ spec.add_development_dependency 'rubocop', '~> 0.40', '>= 0.40.0'
27
+ end
metadata ADDED
@@ -0,0 +1,134 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: passman
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Alejandro Bezdjian
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-06-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: colorize
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.7'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 0.7.5
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '0.7'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 0.7.5
33
+ - !ruby/object:Gem::Dependency
34
+ name: bundler
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: 1.3.0
40
+ - - "<"
41
+ - !ruby/object:Gem::Version
42
+ version: '2.0'
43
+ type: :development
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: 1.3.0
50
+ - - "<"
51
+ - !ruby/object:Gem::Version
52
+ version: '2.0'
53
+ - !ruby/object:Gem::Dependency
54
+ name: byebug
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ type: :development
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ - !ruby/object:Gem::Dependency
68
+ name: rubocop
69
+ requirement: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - "~>"
72
+ - !ruby/object:Gem::Version
73
+ version: '0.40'
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: 0.40.0
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '0.40'
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: 0.40.0
87
+ description: PassMan is a password manager that stores your passwords encrypted, let's
88
+ you retreive them and create new ones.
89
+ email: alebezdjian@gmail.com
90
+ executables:
91
+ - passman
92
+ extensions: []
93
+ extra_rdoc_files: []
94
+ files:
95
+ - ".gitignore"
96
+ - ".rspec"
97
+ - ".rubocop.yml"
98
+ - ".travis.yml"
99
+ - Gemfile
100
+ - LICENSE.md
101
+ - README.md
102
+ - Rakefile
103
+ - bin/passman
104
+ - lib/passman.rb
105
+ - lib/passman/crypto.rb
106
+ - lib/passman/password_generator.rb
107
+ - lib/passman/version.rb
108
+ - passman.gemspec
109
+ homepage: https://github.com/alebian/passman
110
+ licenses:
111
+ - MIT
112
+ metadata: {}
113
+ post_install_message:
114
+ rdoc_options: []
115
+ require_paths:
116
+ - lib
117
+ required_ruby_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ requirements: []
128
+ rubyforge_project:
129
+ rubygems_version: 2.5.1
130
+ signing_key:
131
+ specification_version: 4
132
+ summary: Password manager.
133
+ test_files: []
134
+ has_rdoc: