haddock 0.2.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.
data/History.txt ADDED
@@ -0,0 +1,28 @@
1
+ === 0.2.0 / 2009-03-29
2
+
3
+ * 1 major enhancement
4
+
5
+ * Changed "haddock" to "ha-gen" for Haskell compliance.
6
+
7
+
8
+ === 0.1.1 / 2009-03-29
9
+
10
+ * 2 minor enhancements
11
+
12
+ * Add version option to command-line utility.
13
+ * Bumping up version numbers to improve credibility.
14
+
15
+
16
+ === 0.1.0 / 2009-03-29
17
+
18
+ * 2 minor enhancements
19
+
20
+ * Friendlier command-line errors.
21
+ * General cleanup.
22
+
23
+
24
+ === 0.0.1 / 2009-03-28
25
+
26
+ * 1 major enhancement
27
+
28
+ * Birthday!
data/Manifest.txt ADDED
@@ -0,0 +1,8 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ bin/ha-gen
6
+ lib/haddock.rb
7
+ test/names.txt
8
+ test/test_haddock.rb
data/README.txt ADDED
@@ -0,0 +1,81 @@
1
+ = haddock
2
+
3
+ http://github.com/stephencelis/haddock
4
+
5
+
6
+ == DESCRIPTION
7
+
8
+ A more memorable password generator. Swordfish? No, I got tired of that. I
9
+ changed it.
10
+
11
+
12
+ == FEATURES/PROBLEMS
13
+
14
+ * Secure!
15
+
16
+
17
+ == SYNOPSIS
18
+
19
+ In your apps:
20
+
21
+ require "rubygems"
22
+ require "haddock"
23
+ include Haddock
24
+ Password.generate # => "bowl9&bracky"
25
+ Password.generate(30) # => "Phlebotomus2473?nonconditioned"
26
+ Password.generate(8) # => "amy7@rax"
27
+
28
+
29
+ On the command line:
30
+
31
+ % ha-gen
32
+ bowl9&bracky
33
+ % ha-gen -l31
34
+ symbolistically5<overthwartways
35
+
36
+
37
+ == REQUIREMENTS
38
+
39
+ A newline-delimited words file. By default, it uses "/usr/share/dict/words" or
40
+ "/usr/share/words".
41
+
42
+ Otherwise:
43
+
44
+ Haddock::Password.diction = "/path/to/words"
45
+
46
+
47
+ Or:
48
+
49
+ % ha-gen -f /path/to/words
50
+
51
+
52
+ == INSTALL
53
+
54
+ GitHub:
55
+
56
+ % gem install stephencelis-haddock --source=http://gems.github.com
57
+
58
+
59
+ == LICENSE
60
+
61
+ (The MIT License)
62
+
63
+ (c) 2009-* Stephen Celis, stephen@stephencelis.com.
64
+
65
+ Permission is hereby granted, free of charge, to any person obtaining a copy
66
+ of this software and associated documentation files (the "Software"), to deal
67
+ in the Software without restriction, including without limitation the rights
68
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
69
+ copies of the Software, and to permit persons to whom the Software is
70
+ furnished to do so, subject to the following conditions:
71
+
72
+ The above copyright notice and this permission notice shall be included in all
73
+ copies or substantial portions of the Software.
74
+
75
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
76
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
77
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
78
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
79
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
80
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
81
+ SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ $: << File.dirname(__FILE__) + "/lib"
2
+ require "rubygems"
3
+ require "hoe"
4
+ require "haddock"
5
+
6
+ Hoe.new('haddock', Haddock::VERSION) do |p|
7
+ p.developer('Stephen Celis', 'stephen@stephencelis.com')
8
+ p.remote_rdoc_dir = ''
9
+ end
data/bin/ha-gen ADDED
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $: << File.dirname(__FILE__) + "/../lib"
4
+ require "optparse"
5
+ require "haddock"
6
+ include Haddock
7
+
8
+ parser = OptionParser.new do |opts|
9
+ opts.banner = "usage: #{File.basename($0)} [options]"
10
+
11
+ opts.on("-V", "--version") do
12
+ require 'capistrano/version'
13
+ puts "#{File.basename($0)}: v#{Haddock::VERSION}"
14
+ exit
15
+ end
16
+
17
+ opts.on("-h", "--help") do
18
+ puts opts
19
+ exit
20
+ end
21
+
22
+ opts.on("-l", "--length [length]") do |value|
23
+ raise Password::LengthError, "Invalid length" if value.match(/\D/)
24
+ @length = value.to_i
25
+ end
26
+
27
+ opts.on("-f", "--words [words file]") do |value|
28
+ Password.diction = value
29
+ end
30
+ end
31
+
32
+ begin
33
+ parser.parse!
34
+ puts @length ? Password.generate(@length) : Password.generate
35
+ rescue OptionParser::ParseError, Password::LengthError => error
36
+ warn "#{File.basename($0)}: #{error.message} " +
37
+ "(must be between #{Password::MINIMUM} and #{Password::MAXIMUM})."
38
+ puts parser
39
+ exit 1
40
+ rescue Password::NoWordsError => error
41
+ warn "#{File.basename($0)}: #{error.message}."
42
+ puts "Word lists are available here: http://wordlist.sourceforge.net"
43
+ puts parser
44
+ exit 1
45
+ end
data/lib/haddock.rb ADDED
@@ -0,0 +1,81 @@
1
+ # A more memorable password generator. Swordfish? No, I got tired of that. I
2
+ # changed it.
3
+ module Haddock
4
+ VERSION = '0.2.0'
5
+
6
+ module Password
7
+ MINIMUM = 8
8
+ MAXIMUM = 31
9
+ DEFAULT = 12
10
+
11
+ SYMBOLS = '`~!@#$%^&*()-_=+[{]}\\|;:\'",<.>/?'
12
+
13
+ class << self
14
+ @@paths = %w(/usr/share/dict/words /usr/share/words)
15
+
16
+ # Generates a more memorable password. Its one optional argument
17
+ # determines the length of the generated password, and cannot be less
18
+ # than 8 or greater than 31 characters (default: 12).
19
+ #
20
+ # Password.generate # => "bowl9&bracky"
21
+ # Password.generate(30) # => "Phlebotomus2473?nonconditioned"
22
+ # Password.generate(8) # => "amy7@rax"
23
+ def generate(length = DEFAULT)
24
+ unless defined? @@diction
25
+ self.diction = @@paths.find { |path| File.exist? path }
26
+ end
27
+
28
+ raise LengthError, "Invalid length" unless length.is_a? Integer
29
+ raise LengthError, "Password length is too short" if length < MINIMUM
30
+ raise LengthError, "Password length is too long" if length > MAXIMUM
31
+
32
+ words_limit = length * 0.75 # Ensure over-proportionate word lengths.
33
+
34
+ begin
35
+ words = %W(#{random_word} #{random_symbol}#{random_word})
36
+ words_length = words.to_s.length
37
+ end until words_length < length && words_length > words_limit
38
+
39
+ words.join random_number(length - words_length)
40
+ end
41
+
42
+ # Sets the dictionary. Uses "/usr/share/dict/words" or
43
+ # "/usr/share/words" otherwise.
44
+ #
45
+ # Password.diction = File.expand_path(__FILE__) + "/my_words.txt"
46
+ def diction=(path)
47
+ @@diction = IO.readlines path
48
+ rescue TypeError
49
+ raise NoWordsError, "No words file found"
50
+ rescue Errno::ENOENT
51
+ raise NoWordsError, "No words file at #{path.inspect}"
52
+ end
53
+
54
+ private
55
+
56
+ def random_word
57
+ @@diction[rand(@@diction.length)].chomp
58
+ end
59
+
60
+ def random_symbol
61
+ SYMBOLS[rand(SYMBOLS.length), 1]
62
+ end
63
+
64
+ def random_number(digits)
65
+ begin
66
+ number = rand(10 ** digits).to_s
67
+ end until number.length == digits
68
+
69
+ number
70
+ end
71
+ end
72
+
73
+ # Raised if a password is generated with too few or too many characters.
74
+ class LengthError < ArgumentError
75
+ end
76
+
77
+ # Raised if no words file is found.
78
+ class NoWordsError < StandardError
79
+ end
80
+ end
81
+ end
data/test/names.txt ADDED
@@ -0,0 +1,2 @@
1
+ Mary
2
+ sturgeon
@@ -0,0 +1,60 @@
1
+ require "test/unit"
2
+ require "haddock"
3
+
4
+ class TestHaddock < Test::Unit::TestCase
5
+ include Haddock
6
+
7
+ def test_generates_password
8
+ password = Password.generate
9
+ assert_instance_of String, password
10
+ assert_equal Password::DEFAULT, password.length
11
+ end
12
+
13
+ def test_password_format
14
+ symbols = "[#{Regexp.quote Password::SYMBOLS}]"
15
+ pattern = /^[a-z]+[0-9]+#{symbols}{1}[a-z]+/i
16
+ assert_match(pattern, Password.generate)
17
+ end
18
+
19
+ def test_generates_variable_password
20
+ assert_equal Password.generate(18).length, 18
21
+ end
22
+
23
+ def test_accepts_alternate_wordlist
24
+ Password.diction = path = File.dirname(__FILE__) + "/names.txt"
25
+ pattern = Regexp.new File.read(path).split.join("|")
26
+ assert_match(pattern, Password.generate(14))
27
+ ensure
28
+ Password.diction = "/usr/share/dict/words"
29
+ end
30
+
31
+ def test_fail_on_too_short
32
+ assert_raise Password::LengthError do
33
+ Password.generate(Password::MINIMUM - 1)
34
+ end
35
+ end
36
+
37
+ def test_fail_on_too_long
38
+ assert_raise Password::LengthError do
39
+ Password.generate(Password::MAXIMUM + 1)
40
+ end
41
+ end
42
+
43
+ def test_fail_on_invalid
44
+ assert_raise Password::LengthError do
45
+ Password.generate("invalid")
46
+ end
47
+ end
48
+
49
+ def test_fail_on_invalid_path
50
+ assert_raise Password::NoWordsError do
51
+ Password.diction = "invalid/path"
52
+ end
53
+ end
54
+
55
+ def test_fail_on_nil_path
56
+ assert_raise Password::NoWordsError do
57
+ Password.diction = nil
58
+ end
59
+ end
60
+ end
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: haddock
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Stephen Celis
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-04-01 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: hoe
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.11.0
24
+ version:
25
+ description: A more memorable password generator. Swordfish? No, I got tired of that. I changed it.
26
+ email:
27
+ - stephen@stephencelis.com
28
+ executables:
29
+ - ha-gen
30
+ extensions: []
31
+
32
+ extra_rdoc_files:
33
+ - History.txt
34
+ - Manifest.txt
35
+ - README.txt
36
+ files:
37
+ - History.txt
38
+ - Manifest.txt
39
+ - README.txt
40
+ - Rakefile
41
+ - bin/ha-gen
42
+ - lib/haddock.rb
43
+ - test/names.txt
44
+ - test/test_haddock.rb
45
+ has_rdoc: true
46
+ homepage: http://github.com/stephencelis/haddock
47
+ post_install_message:
48
+ rdoc_options:
49
+ - --main
50
+ - README.txt
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ version:
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: "0"
64
+ version:
65
+ requirements: []
66
+
67
+ rubyforge_project: haddock
68
+ rubygems_version: 1.3.1
69
+ signing_key:
70
+ specification_version: 2
71
+ summary: A more memorable password generator
72
+ test_files:
73
+ - test/test_haddock.rb