passr 0.1.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 +7 -0
- data/.gitignore +13 -0
- data/.travis.yml +5 -0
- data/CONTRIBUTING.md +51 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +87 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/exe/passr +3 -0
- data/lib/passr.rb +36 -0
- data/lib/passr/cli.rb +17 -0
- data/lib/passr/encryptor.rb +84 -0
- data/lib/passr/generator.rb +128 -0
- data/lib/passr/version.rb +3 -0
- data/passr.gemspec +34 -0
- metadata +174 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d9481105a3116d5cf9fe573d8f7de6f9a73c6fe0
|
4
|
+
data.tar.gz: d58ba8018df9c045a1423fc218e05c291c41b20d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a23c5ab526dd433be3a47142bb6b127e77a80bfdf790b203059e4bcfb7d3cbac31bf4c3949b0ebfff28906961d2551f52db8d61b52aa7ff7964f91b3822f83ed
|
7
|
+
data.tar.gz: b70a872b3fd54ad06e91ef24e9b7c24cff8b4871475e9a7aac2cc57dadf6b61509259640deeb42acbbca998d77be99d68c545c44c31c4301473cf512a76bf245
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# Contributing
|
2
|
+
|
3
|
+
Thank you for your interest in contributing! We welcome developers of all skill levels to contribute to Passr and will provide issues for those new to open-source and veterans alike. All tasks that we are looking to complete can be found in the [Issues](https://github.com/rdavid1099/passr/issues) section. If you find a bug or would like to implement new functionality, please feel free to contact the owner, [rdavid1099@gmail.com](mailto:rdavid1099@gmail.com).
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
- Fork and clone Passr to your local machine, use [this guide](https://help.github.com/articles/fork-a-repo/) if you don't know how to do that.
|
8
|
+
- Set the upstream remote so you can keep your copy of Passr synced with the original. To do that go to your terminal and `cd` into your cloned Passr directory. Then user one of the following commands:
|
9
|
+
|
10
|
+
If you have ssh set up with Git
|
11
|
+
```
|
12
|
+
$ git remote add upstream git@github.com:rdavid1099/passr.git
|
13
|
+
```
|
14
|
+
Otherwise
|
15
|
+
```
|
16
|
+
$ git remote add upstream https://github.com/rdavid1099/passr.git
|
17
|
+
```
|
18
|
+
|
19
|
+
- From the root directory run `bundle install` to install all gem dependencies.
|
20
|
+
- Run `rake` to run all tests.
|
21
|
+
|
22
|
+
## Code Style
|
23
|
+
|
24
|
+
While we encourage creativity and "clever" code, your implementation must follow basic Ruby standards and practices. This includes:
|
25
|
+
|
26
|
+
- Write readable and succinct code, and use standard functions in Ruby to the best of your knowledge.
|
27
|
+
- Blank lines should contain no spaces, and there should be no additional white space following the end of a line of code.
|
28
|
+
- Follow the [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) principle.
|
29
|
+
- Have fun!
|
30
|
+
|
31
|
+
## Testing
|
32
|
+
|
33
|
+
Tests are imperative to creating a functional and success program. We follow test driven development, and writing test cases should be done before any lines of code are written. Our test suite uses [Minitest](http://ruby-doc.org/stdlib-2.0.0/libdoc/minitest/rdoc/MiniTest.html) and should follow basic Minitest formatting and style. All features/ bugs must include coinciding tests to confirm their functionality, including sad cases.
|
34
|
+
|
35
|
+
### Writing Tests
|
36
|
+
|
37
|
+
Before creating a new test method or file, be sure to review `./test/test_helper.rb`. A lot of base logic is located in that file.
|
38
|
+
|
39
|
+
### Running Tests
|
40
|
+
|
41
|
+
Run `rake test` to run all tests in test suite.
|
42
|
+
|
43
|
+
## Documentation
|
44
|
+
|
45
|
+
If adding new functionality, be sure to keep the documentation up-to-date. We use [YARD](http://yardoc.org/) for documentation. Be sure to follow the style present throughout the codebase and refer to docs for any additional questions. For functions, write a description, parameters (if any), and the return value (if non-void).
|
46
|
+
|
47
|
+
To view the most recent documentation run `yardoc` from the root directory and then run `yard server`. In your favorite browser, go to `localhost:8808`. You can also check out our [online documentation](http://www.rubydoc.info/github/rdavid1099/passr/master).
|
48
|
+
|
49
|
+
## Pull Requests
|
50
|
+
|
51
|
+
All branches should be based off the `development` branch and written using the following format, `ISSUE_NUMBER-SUMMARY-OF-ISSUE` (ex: `12-create-contributing`). Before submitting a pull request, run `rake test:all` in the top-level directory to verify that all tests are passing. Make your pull request to `development` unless stated otherwise in the issue tracker. We will check for new pull requests at the end of every day and review/ comment on them as necessary.
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2017 Ryan Workman
|
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,87 @@
|
|
1
|
+
# Passr
|
2
|
+
[](https://rubygems.org/gems/passr)
|
3
|
+
[](https://travis-ci.org/rdavid1099/passr)
|
4
|
+
[](https://coveralls.io/github/rdavid1099/passr?branch=master)
|
5
|
+
[](https://github.com/rdavid1099/passr/issues)
|
6
|
+
|
7
|
+
:lock: "If you're able to memorize your passwords, you're doing it wrong."
|
8
|
+
|
9
|
+
Passr is a simple Ruby gem handling password generation, encryption and decryption.
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Add this line to your application's Gemfile:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
gem 'passr'
|
17
|
+
```
|
18
|
+
|
19
|
+
And then execute:
|
20
|
+
|
21
|
+
$ bundle
|
22
|
+
|
23
|
+
Or install it yourself as:
|
24
|
+
|
25
|
+
$ gem install passr
|
26
|
+
|
27
|
+
After installing the gem, from the project's root folder run `bundle exec passr install` to generate a secret encryption key. This key will be saved to the file `./config/encryptor.yml` and add it to the project's `.gitignore`. This file must be present for encryption and decryption. Be sure to make a backup of this key. If it is ever moved or deleted from the project, all encrypted passwords will be lost forever.
|
28
|
+
|
29
|
+
## Usage
|
30
|
+
|
31
|
+
### Generating Encrypted Passwords
|
32
|
+
|
33
|
+
Using Passr is a simple as requiring the gem and calling `Passr.generate`. The method will return a Hash containing the `:password`, `:nonce`, and `:encrypted_password`.
|
34
|
+
- `:password` is the unencrypted generated password.
|
35
|
+
- `:encrypted_password` is the encrypted generated password using the secret key stored in `./config/encryption.yml` and the nonce.
|
36
|
+
- `:nonce` is the nonce used to create the encrypted password. The nonce must be saved and provided for decryption.
|
37
|
+
|
38
|
+
`Passr.generate` has multiple options that can be passed in as arguments to customize the generated passwords.
|
39
|
+
- `:length` will create a generated password with the given number of characters. Length defaults to 15 characters and must be under 40 characters.
|
40
|
+
- `:nonce` will create an encryption of the generated password using the given nonce. It will throw an error if the nonce is not compatible with the secret key saved in `./config/encryption.yml`.
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
require 'passr'
|
44
|
+
|
45
|
+
Passr.generate
|
46
|
+
# => {:password => "$4!~j9t=18%f+@I",
|
47
|
+
# :encrypted_password => "XnShJLuUyArMMkMQNeQismHLukTeRa1LMJHRc39Avw==",
|
48
|
+
# :nonce => "ee/1Z2YlXVkqmPn1CRPtukTzMa4fNh99"}
|
49
|
+
|
50
|
+
Passr.generate(length: 20,
|
51
|
+
nonce: "ee/1Z2YlXVkqmPn1CRPtukTzMa4fNh99")
|
52
|
+
# => {:nonce => "ee/1Z2YlXVkqmPn1CRPtukTzMa4fNh99",
|
53
|
+
# :password => "l~qy5g!j78=ndx2614N@",
|
54
|
+
# :encrypted_password => "ZYrISzJiNpn2JpB+FrEgeymB6kOBG/gcNpHJezB4xPV3eXjV"}
|
55
|
+
```
|
56
|
+
|
57
|
+
### Decrypting Passwords
|
58
|
+
|
59
|
+
Simply decrypt any generated passwords calling `Passr.reveal` and passing in the encrypted password and the nonce used to encrypt the password as arguments and it will return the decrypted password as a String.
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
require 'passr'
|
63
|
+
|
64
|
+
Passr.generate
|
65
|
+
# => {:password => "$4!~j9t=18%f+@I",
|
66
|
+
# :encrypted_password => "XnShJLuUyArMMkMQNeQismHLukTeRa1LMJHRc39Avw==",
|
67
|
+
# :nonce => "ee/1Z2YlXVkqmPn1CRPtukTzMa4fNh99"}
|
68
|
+
|
69
|
+
Passr.reveal(password: "XnShJLuUyArMMkMQNeQismHLukTeRa1LMJHRc39Avw==",
|
70
|
+
nonce: "ee/1Z2YlXVkqmPn1CRPtukTzMa4fNh99")
|
71
|
+
# => "$4!~j9t=18%f+@I"
|
72
|
+
```
|
73
|
+
|
74
|
+
## Development
|
75
|
+
|
76
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
77
|
+
|
78
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
79
|
+
|
80
|
+
## Contributing
|
81
|
+
|
82
|
+
Contributions are welcome! Be sure to read our [contributing guide](https://github.com/rdavid1099/passr/blob/master/CONTRIBUTING.md) before working on an issue. Bug reports and pull requests are welcome on GitHub at https://github.com/rdavid1099/passr.
|
83
|
+
|
84
|
+
|
85
|
+
## License
|
86
|
+
|
87
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "passr"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/exe/passr
ADDED
data/lib/passr.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'passr/version'
|
2
|
+
require 'passr/encryptor'
|
3
|
+
require 'passr/generator'
|
4
|
+
|
5
|
+
# Overall Passr functionality contained within module
|
6
|
+
module Passr
|
7
|
+
# Generate an encrypted password
|
8
|
+
#
|
9
|
+
# @param [Hash] options options for password generating
|
10
|
+
# @option options [Integer] :length length of characters of generated password
|
11
|
+
# @option options [String] :nonce nonce to encrypt password using known nonce
|
12
|
+
# @return [Hash] data regarding the encrypted generated password
|
13
|
+
def self.generate(**options)
|
14
|
+
encryptor = Passr::Encryptor.new(options[:nonce])
|
15
|
+
generated_password = Passr::Generator.password(options[:length])
|
16
|
+
encrypted_password = encryptor.encrypt(generated_password)
|
17
|
+
{nonce: encryptor.nonce,
|
18
|
+
password: generated_password,
|
19
|
+
encrypted_password: encrypted_password}
|
20
|
+
end
|
21
|
+
|
22
|
+
# Decrypt and reveal encrypted password
|
23
|
+
#
|
24
|
+
# @param [Hash] params params of necessary information for decryption
|
25
|
+
# @option params [String] :password encrypted password returned from Passr.generate
|
26
|
+
# @option params [String] :nonce nonce returned from Passr.generate
|
27
|
+
# @return [String] decrypted password
|
28
|
+
def self.reveal(**params)
|
29
|
+
begin
|
30
|
+
encryptor = Passr::Encryptor.new(params[:nonce])
|
31
|
+
encryptor.decrypt(params[:password])
|
32
|
+
rescue => e
|
33
|
+
false
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/passr/cli.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'passr'
|
3
|
+
|
4
|
+
module Passr
|
5
|
+
class CLI < Thor
|
6
|
+
|
7
|
+
desc 'install Passr in project', 'Creates `./config` if not present and generates secret key and YAML for encryption'
|
8
|
+
def install
|
9
|
+
begin
|
10
|
+
Passr::Encryptor.install
|
11
|
+
puts "./config/encryptor.yml successfully created.\nDo NOT remove this file or all encrypted passwords will be lost."
|
12
|
+
rescue => e
|
13
|
+
puts e
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'base64'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'rbnacl/libsodium'
|
5
|
+
|
6
|
+
module Passr
|
7
|
+
# Path searching for yaml file containing encryption information
|
8
|
+
PATH = File.expand_path('./config/encryptor.yml')
|
9
|
+
|
10
|
+
class Encryptor
|
11
|
+
attr_reader :raw_nonce
|
12
|
+
|
13
|
+
def initialize(nonce = nil)
|
14
|
+
@secret_key = load_secret_key || Encryptor.install
|
15
|
+
@secret_box = create_secret_box
|
16
|
+
@raw_nonce = get_raw_nonce(nonce)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.generate_secret_key
|
20
|
+
key = RbNaCl::Random.random_bytes(RbNaCl::SecretBox.key_bytes)
|
21
|
+
File.open(PATH, 'w') do |f|
|
22
|
+
f.write "---\nSECRET_KEY: #{Base64.encode64(key)}"
|
23
|
+
end
|
24
|
+
key
|
25
|
+
end
|
26
|
+
|
27
|
+
def encrypt(password)
|
28
|
+
raw_encryption = secret_box.encrypt(raw_nonce, password)
|
29
|
+
Base64.encode64(raw_encryption).chomp
|
30
|
+
end
|
31
|
+
|
32
|
+
def decrypt(encrypted_password)
|
33
|
+
raw_encryption = Base64.decode64(encrypted_password)
|
34
|
+
secret_box.decrypt(raw_nonce, raw_encryption)
|
35
|
+
end
|
36
|
+
|
37
|
+
def nonce
|
38
|
+
Base64.encode64(raw_nonce).chomp
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.install
|
42
|
+
unless File.exists? PATH
|
43
|
+
FileUtils::mkdir_p File.expand_path('./config/')
|
44
|
+
update_gitignore
|
45
|
+
generate_secret_key
|
46
|
+
else
|
47
|
+
raise RuntimeError, "./config/encryptor.yml already exists."
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.update_gitignore
|
52
|
+
gitignore = File.expand_path('./.gitignore')
|
53
|
+
unless File.read(gitignore).split("\n").include?('/config/encryptor.yml')
|
54
|
+
open(gitignore, 'a') do |f|
|
55
|
+
f << "\n# Ignore Passr Encryption Configuration\n/config/encryptor.yml"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
attr_reader :secret_key, :secret_box
|
62
|
+
|
63
|
+
def load_secret_key
|
64
|
+
begin
|
65
|
+
encrypted_key = YAML.load_file(PATH)['SECRET_KEY']
|
66
|
+
Base64.decode64(encrypted_key)
|
67
|
+
rescue => e
|
68
|
+
false
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def get_raw_nonce(nonce)
|
73
|
+
if nonce
|
74
|
+
Base64.decode64(nonce)
|
75
|
+
else
|
76
|
+
RbNaCl::Random.random_bytes(secret_box.nonce_bytes)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def create_secret_box
|
81
|
+
RbNaCl::SecretBox.new(secret_key)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
module Passr
|
2
|
+
# 2-D array of all possible characters that can be used in a password
|
3
|
+
CHARACTERS = [['!','$','%','+','/','=','@','~'],
|
4
|
+
('0'..'9').to_a,
|
5
|
+
('a'..'z').to_a]
|
6
|
+
|
7
|
+
# Handles account/ username creation and respective password generation
|
8
|
+
class Generator
|
9
|
+
# Generates password of given length
|
10
|
+
#
|
11
|
+
# @param [Integer] length length of characters for generated password
|
12
|
+
# @return [String] generated password of give length
|
13
|
+
def self.password(length = nil)
|
14
|
+
length = 15 if length.nil? || length.to_i > 40
|
15
|
+
generated = Array.new(length).map { random_character }.join('')
|
16
|
+
sanitize(generated)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Sanitize password to ensure there are all unique characters and there is at
|
20
|
+
# least one special character, capital letter, lowercase letter, and number
|
21
|
+
#
|
22
|
+
# @param [String] password pre-sanitized/ initially generated password
|
23
|
+
# @return [String] sanitized and completely unique password
|
24
|
+
def self.sanitize(password)
|
25
|
+
password.add_special!(CHARACTERS[0]) if password.scan(/[!@#$%^&*()]/).empty?
|
26
|
+
password.add_number!(CHARACTERS[1]) if password.scan(/[0-9]/).empty?
|
27
|
+
password.add_capital_letter!(CHARACTERS[2]) if password.scan(/[A-Z]/).empty?
|
28
|
+
password.unique_chars!
|
29
|
+
sanitize(password) unless is_sanitary?(password)
|
30
|
+
return password
|
31
|
+
end
|
32
|
+
|
33
|
+
# @return [String] a random character from the constant CHARACTERS
|
34
|
+
def self.random_character
|
35
|
+
character_set = CHARACTERS[rand(3)]
|
36
|
+
character_set[rand(character_set.length)]
|
37
|
+
end
|
38
|
+
|
39
|
+
# Get a unique character that is not in current password
|
40
|
+
#
|
41
|
+
# @param [String] password generated password
|
42
|
+
# @return [String] unique character that is not present in password
|
43
|
+
def self.new_character(password)
|
44
|
+
CHARACTERS.each do |set|
|
45
|
+
set.each do |char|
|
46
|
+
return char unless password.include?(char)
|
47
|
+
return char.upcase unless password.include?(char.upcase)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Determine if password meets all security parameters
|
53
|
+
#
|
54
|
+
# @param [String] password generated password
|
55
|
+
# @return [Boolean] true if password meets are required security measures
|
56
|
+
def self.is_sanitary?(password)
|
57
|
+
password.scan(/[!@#$%^&*()]/).count > 0 &&
|
58
|
+
password.scan(/[0-9]/).count > 0 &&
|
59
|
+
password.scan(/[A-Z]/).count > 0 &&
|
60
|
+
password.scan(/[a-z]/).count > 0 &&
|
61
|
+
is_all_unique_characters?(password)
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
# Determine if password has all unique characters
|
66
|
+
#
|
67
|
+
# @param [String] password generated password
|
68
|
+
# @return [Boolean] true if password has all unique characters
|
69
|
+
def self.is_all_unique_characters?(password)
|
70
|
+
password.length.times do |i|
|
71
|
+
password.chars.each_with_index do |char, index|
|
72
|
+
unless i == index
|
73
|
+
return false if password[i] == char
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
true
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# Extends Ruby String Class to handle special bang methods for password generating
|
83
|
+
class String
|
84
|
+
# Add a special character to given string
|
85
|
+
#
|
86
|
+
# @param [Array] special_chars list of special characters
|
87
|
+
# @return [String] replaces self with a special character in the place another random character
|
88
|
+
def add_special!(special_chars)
|
89
|
+
sanitized = self
|
90
|
+
sanitized[rand(sanitized.length)] = special_chars[rand(special_chars.length)]
|
91
|
+
self.replace(sanitized)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Add a number to given string
|
95
|
+
#
|
96
|
+
# @param [Array] numbers list of numbers, preferably single digits (0-9)
|
97
|
+
# @return [String] replaces self with a number in the place another random character
|
98
|
+
def add_number!(numbers)
|
99
|
+
sanitized = self
|
100
|
+
sanitized[rand(sanitized.length)] = numbers[rand(numbers.length)]
|
101
|
+
self.replace(sanitized)
|
102
|
+
end
|
103
|
+
|
104
|
+
# Add a capital letter to given string
|
105
|
+
#
|
106
|
+
# @param [Array] letters list of letters, preferably entire lowercase alphabet (a-z)
|
107
|
+
# @return [String] replaces self with an upper case letter in the place another random character
|
108
|
+
def add_capital_letter!(letters)
|
109
|
+
sanitized = self
|
110
|
+
sanitized[rand(sanitized.length)] = letters[rand(letters.length)].upcase
|
111
|
+
self.replace(sanitized)
|
112
|
+
end
|
113
|
+
|
114
|
+
# Make string entirely unique characters
|
115
|
+
#
|
116
|
+
# @return [String] replaces self with a string that is made up of all unique characters
|
117
|
+
def unique_chars!
|
118
|
+
sanitized = self
|
119
|
+
sanitized.length.times do |i|
|
120
|
+
sanitized.chars.each_with_index do |char, index|
|
121
|
+
unless i == index
|
122
|
+
sanitized[i] = Passr::Generator.new_character(sanitized) if sanitized[i] == char
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
self.replace(sanitized)
|
127
|
+
end
|
128
|
+
end
|
data/passr.gemspec
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'passr/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "passr"
|
8
|
+
spec.version = Passr::VERSION
|
9
|
+
spec.authors = ["Ryan Workman"]
|
10
|
+
spec.email = ["rdavid1099@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Generates random passwords of a given length encrypted using RbNaCl}
|
13
|
+
spec.description = %q{Passr is a simple Ruby gem handling password generation, encryption and decryption.}
|
14
|
+
spec.homepage = "https://github.com/rdavid1099/passr"
|
15
|
+
spec.license = "MIT"
|
16
|
+
spec.bindir = "exe"
|
17
|
+
spec.has_rdoc = "yard"
|
18
|
+
|
19
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
20
|
+
f.match(%r{^(test|spec|features)/})
|
21
|
+
end
|
22
|
+
spec.bindir = "exe"
|
23
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
24
|
+
spec.require_paths = ["lib"]
|
25
|
+
|
26
|
+
spec.add_development_dependency "bundler", "~> 1.14"
|
27
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
28
|
+
spec.add_development_dependency "minitest", "~> 5.0"
|
29
|
+
spec.add_development_dependency "simplecov", "0.14.1"
|
30
|
+
spec.add_development_dependency 'coveralls'
|
31
|
+
spec.add_development_dependency "yard", "0.9.9"
|
32
|
+
spec.add_dependency "rbnacl-libsodium", "1.0.11"
|
33
|
+
spec.add_dependency "thor"
|
34
|
+
end
|
metadata
ADDED
@@ -0,0 +1,174 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: passr
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ryan Workman
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-05-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.14'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.14'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '5.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '5.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: simplecov
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.14.1
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.14.1
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: coveralls
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: yard
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.9.9
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.9.9
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rbnacl-libsodium
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 1.0.11
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 1.0.11
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: thor
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
description: Passr is a simple Ruby gem handling password generation, encryption and
|
126
|
+
decryption.
|
127
|
+
email:
|
128
|
+
- rdavid1099@gmail.com
|
129
|
+
executables:
|
130
|
+
- passr
|
131
|
+
extensions: []
|
132
|
+
extra_rdoc_files: []
|
133
|
+
files:
|
134
|
+
- ".gitignore"
|
135
|
+
- ".travis.yml"
|
136
|
+
- CONTRIBUTING.md
|
137
|
+
- Gemfile
|
138
|
+
- LICENSE.txt
|
139
|
+
- README.md
|
140
|
+
- Rakefile
|
141
|
+
- bin/console
|
142
|
+
- bin/setup
|
143
|
+
- exe/passr
|
144
|
+
- lib/passr.rb
|
145
|
+
- lib/passr/cli.rb
|
146
|
+
- lib/passr/encryptor.rb
|
147
|
+
- lib/passr/generator.rb
|
148
|
+
- lib/passr/version.rb
|
149
|
+
- passr.gemspec
|
150
|
+
homepage: https://github.com/rdavid1099/passr
|
151
|
+
licenses:
|
152
|
+
- MIT
|
153
|
+
metadata: {}
|
154
|
+
post_install_message:
|
155
|
+
rdoc_options: []
|
156
|
+
require_paths:
|
157
|
+
- lib
|
158
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
159
|
+
requirements:
|
160
|
+
- - ">="
|
161
|
+
- !ruby/object:Gem::Version
|
162
|
+
version: '0'
|
163
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
164
|
+
requirements:
|
165
|
+
- - ">="
|
166
|
+
- !ruby/object:Gem::Version
|
167
|
+
version: '0'
|
168
|
+
requirements: []
|
169
|
+
rubyforge_project:
|
170
|
+
rubygems_version: 2.6.7
|
171
|
+
signing_key:
|
172
|
+
specification_version: 4
|
173
|
+
summary: Generates random passwords of a given length encrypted using RbNaCl
|
174
|
+
test_files: []
|