perch 0.2.3

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.
@@ -0,0 +1,23 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'autotest/restart'
4
+
5
+ # Autotest.add_hook :initialize do |at|
6
+ # at.extra_files << "../some/external/dependency.rb"
7
+ #
8
+ # at.libs << ":../some/external"
9
+ #
10
+ # at.add_exception 'vendor'
11
+ #
12
+ # at.add_mapping(/dependency.rb/) do |f, _|
13
+ # at.files_matching(/test_.*rb$/)
14
+ # end
15
+ #
16
+ # %w(TestA TestB).each do |klass|
17
+ # at.extra_class_map[klass] = "test/test_misc.rb"
18
+ # end
19
+ # end
20
+
21
+ # Autotest.add_hook :run_command do |at|
22
+ # system "rake build"
23
+ # end
@@ -0,0 +1,36 @@
1
+ === 0.2.1 / 2009-05-14
2
+
3
+ * 1 major, minor enhancement
4
+
5
+ * Ruby 1.9 compatibility.
6
+
7
+
8
+
9
+ === 0.2.0 / 2009-03-29
10
+
11
+ * 1 major enhancement
12
+
13
+ * Changed "haddock" to "ha-gen" for Haskell compliance.
14
+
15
+
16
+ === 0.1.1 / 2009-03-29
17
+
18
+ * 2 minor enhancements
19
+
20
+ * Add version option to command-line utility.
21
+ * Bumping up version numbers to improve credibility.
22
+
23
+
24
+ === 0.1.0 / 2009-03-29
25
+
26
+ * 2 minor enhancements
27
+
28
+ * Friendlier command-line errors.
29
+ * General cleanup.
30
+
31
+
32
+ === 0.0.1 / 2009-03-28
33
+
34
+ * 1 major enhancement
35
+
36
+ * Birthday!
@@ -0,0 +1,9 @@
1
+ .autotest
2
+ History.rdoc
3
+ Manifest.txt
4
+ README.rdoc
5
+ Rakefile
6
+ bin/ha-gen
7
+ lib/haddock.rb
8
+ test/names.txt
9
+ test/test_haddock.rb
@@ -0,0 +1,84 @@
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
+ For more information:
38
+
39
+ http://stephencelis.com/2009/03/29/whats-the-password-haddock.html
40
+
41
+
42
+ == REQUIREMENTS
43
+
44
+ A newline-delimited words file. By default, it uses "/usr/share/dict/words" or
45
+ "/usr/share/words".
46
+
47
+ Otherwise:
48
+
49
+ Haddock::Password.diction = "/path/to/words"
50
+
51
+
52
+ Or:
53
+
54
+ % ha-gen -f /path/to/words
55
+
56
+
57
+ == INSTALL
58
+
59
+ % [sudo] gem install haddock
60
+
61
+
62
+ == LICENSE
63
+
64
+ (The MIT License)
65
+
66
+ (c) 2009-2010 Stephen Celis, stephen@stephencelis.com.
67
+
68
+ Permission is hereby granted, free of charge, to any person obtaining a copy
69
+ of this software and associated documentation files (the "Software"), to deal
70
+ in the Software without restriction, including without limitation the rights
71
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
72
+ copies of the Software, and to permit persons to whom the Software is
73
+ furnished to do so, subject to the following conditions:
74
+
75
+ The above copyright notice and this permission notice shall be included in all
76
+ copies or substantial portions of the Software.
77
+
78
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
79
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
80
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
81
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
82
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
83
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
84
+ SOFTWARE.
@@ -0,0 +1,17 @@
1
+ $: << File.dirname(__FILE__) + "/lib"
2
+ require "rubygems"
3
+ require "haddock"
4
+
5
+ require "rake/testtask"
6
+ require 'bundler/gem_tasks'
7
+
8
+ desc "Default: run unit tests."
9
+ task :default => :test
10
+
11
+ desc "Run unit tests."
12
+ Rake::TestTask.new(:test) do |t|
13
+ t.libs << 'lib'
14
+ t.libs << 'test'
15
+ t.pattern = 'test/**/test_*.rb'
16
+ t.verbose = true
17
+ end
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $: << File.dirname(__FILE__) + "/../lib"
4
+ require "optparse"
5
+ require "haddock"
6
+ include Haddock
7
+
8
+ OptionParser.new do |opts|
9
+ opts.banner = "usage: #{File.basename($0)} [options]"
10
+
11
+ opts.on("-V", "--version") do
12
+ puts "#{File.basename($0)}: v#{Haddock::VERSION}"
13
+ exit
14
+ end
15
+
16
+ opts.on("-h", "--help") do
17
+ puts opts
18
+ exit
19
+ end
20
+
21
+ opts.on("-l", "--length [length]", Integer) do |value|
22
+ @length = value
23
+ end
24
+
25
+ opts.on("-f", "--words [words file]") do |value|
26
+ Password.diction = value
27
+ end
28
+
29
+ opts.on("-d", "--delimiters [symbols]") do |value|
30
+ Password.delimiters = value
31
+ end
32
+
33
+ begin
34
+ opts.parse!
35
+ puts @length ? Password.generate(@length) : Password.generate
36
+ rescue OptionParser::ParseError, Password::LengthError => error
37
+ warn "#{File.basename($0)}: #{error.message} " +
38
+ "(must be between #{Password::MINIMUM} and #{Password::MAXIMUM})."
39
+ puts opts
40
+ abort
41
+ rescue Password::NoWordsError => error
42
+ warn "#{File.basename($0)}: #{error.message}."
43
+ puts "Word lists are available here: http://wordlist.sourceforge.net"
44
+ puts opts
45
+ abort
46
+ end
47
+ end
@@ -0,0 +1,129 @@
1
+ # A more memorable password generator. Swordfish? No, I got tired of that. I
2
+ # changed it.
3
+ module Haddock
4
+ VERSION = '0.2.3'
5
+
6
+ module Password
7
+ # The minimum password legnth.
8
+ MINIMUM = 8
9
+
10
+ # The maximum password length.
11
+ MAXIMUM = 31
12
+
13
+ # The default password length.
14
+ DEFAULT = 12
15
+
16
+ # Paths used to detect default words files.
17
+ PATHS = %w(/usr/share/dict/words /usr/share/words)
18
+
19
+ #TODO: move these out to file.txt and expand
20
+ ADJECTIVES = %w(reflective happy hungry light breathing handsome purple careful gifted mushy powerful mysterious itchy eager crooked immense loud hissing massive freezing heavy foolish internal ruthless)
21
+ ANIMALS = %w(badger horse squirrel cats beaver armadillo camel dingo fish hamster chipmunk crocodile cougar hedgehog pony shrew puma pocrupine platypus mustang sheep mongoose rabbit fox sloth stallion)
22
+
23
+
24
+ @@delimiters = '`~!@#$%^&*()-_=+[{]}\\|;:\'",<.>/?'
25
+
26
+ class << self
27
+ # Generates a more memorable password. Its one optional argument
28
+ # determines the length of the generated password, and cannot be less
29
+ # than 8 or greater than 31 characters (default: 12). Allows simplification
30
+ # with options
31
+ #
32
+ # Password.generate # => "bowl9&bracky"
33
+ # Password.generate(30) # => "Phlebotomus2473?nonconditioned"
34
+ # Password.generate(8) # => "amy7@rax"
35
+ # Password.generate(8, {:use_delimeter=>false} => "bonk5and"
36
+ # Password.generate(8, {:use_numbers=>false} => "jack!man"
37
+
38
+ def generate(length = DEFAULT, options = {})
39
+ unless defined? @@diction or options[:animal]
40
+ self.diction = PATHS.find { |path| File.exist? path }
41
+ end
42
+ options = {
43
+ :use_delimeter=>true,
44
+ :use_number=>true,
45
+ :animal => false,
46
+ :variable_length=>false
47
+ }.merge(options)
48
+ if length && length.to_s.upcase == "ANY"
49
+ length = rand(DEFAULT)+DEFAULT
50
+ options[:variable_length] = true
51
+ end
52
+
53
+ raise LengthError, "Invalid length" unless length.is_a? Integer
54
+ raise LengthError, "Password length is too short" if length < MINIMUM
55
+ raise LengthError, "Password length is too long" if length > MAXIMUM
56
+
57
+ words_limit = length * 0.75 # Ensure over-proportionate word lengths.
58
+
59
+ begin
60
+ if options[:animal]
61
+ words = %W(#{random_adj} #{random_animal})
62
+ else
63
+ words = %W(#{random_word} #{random_delimiter if options[:use_delimeter]}#{random_word})
64
+ end
65
+ words_length = words.join.length
66
+ return words.join if (words_length == length && !options[:use_number]) || options[:variable_length]
67
+ end until words_length < length && words_length > words_limit && options[:use_number]
68
+
69
+ words.join random_number(length - words_length) if options[:use_number]
70
+ end
71
+
72
+ def generate_fun
73
+ generate("any", {:use_delimeter=>false, :use_number=>false, :animal=>true})
74
+ end
75
+
76
+ # Sets the dictionary. Uses "/usr/share/dict/words" or
77
+ # "/usr/share/words" otherwise.
78
+ #
79
+ # Password.diction = File.expand_path(__FILE__) + "/my_words.txt"
80
+ def diction=(path)
81
+ @@diction = IO.readlines path
82
+ rescue TypeError
83
+ raise NoWordsError, "No words file found"
84
+ rescue Errno::ENOENT
85
+ raise NoWordsError, "No words file at #{path.inspect}"
86
+ end
87
+
88
+ # Sets the list of characters that can delimit words. Default:
89
+ #
90
+ # `~!@#$%^&*()-_=+[{]}\|;:'",<.>/?
91
+ def delimiters=(string)
92
+ @@delimiters = string
93
+ end
94
+
95
+ private
96
+ def random_adj
97
+ ADJECTIVES[rand(ADJECTIVES.length)]
98
+ end
99
+
100
+ def random_animal
101
+ ANIMALS[rand(ANIMALS.length)].capitalize
102
+ end
103
+
104
+ def random_word
105
+ @@diction[rand(@@diction.length)].chomp
106
+ end
107
+
108
+ def random_delimiter
109
+ @@delimiters[rand(@@delimiters.length), 1]
110
+ end
111
+
112
+ def random_number(digits)
113
+ begin
114
+ number = rand(10 ** digits).to_s
115
+ end until number.length == digits
116
+
117
+ number
118
+ end
119
+ end
120
+
121
+ # Raised if a password is generated with too few or too many characters.
122
+ class LengthError < ArgumentError
123
+ end
124
+
125
+ # Raised if no words file is found.
126
+ class NoWordsError < StandardError
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,2 @@
1
+ Mary
2
+ sturgeon
@@ -0,0 +1,89 @@
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 = Password.send :class_variable_get, :@@delimiters
15
+ symbols = "[#{Regexp.quote symbols}]"
16
+ pattern = /^[a-z]+[0-9]+#{symbols}{1}[a-z]+/i
17
+ assert_match(pattern, Password.generate)
18
+ end
19
+
20
+ def test_generates_variable_password
21
+ assert_equal Password.generate(18).length, 18
22
+ end
23
+
24
+ def test_accepts_alternate_wordlist
25
+ Password.diction = path = File.dirname(__FILE__) + "/names.txt"
26
+ pattern = Regexp.new File.read(path).split.join("|")
27
+ assert_match(pattern, Password.generate(14))
28
+ ensure
29
+ Password.diction = "/usr/share/dict/words"
30
+ end
31
+
32
+ def test_accepts_alternate_symbols_list
33
+ Password.delimiters = "X"
34
+ assert_equal "X", Password.send(:random_delimiter)
35
+ end
36
+
37
+ def test_fail_on_too_short
38
+ assert_raise Password::LengthError do
39
+ Password.generate(Password::MINIMUM - 1)
40
+ end
41
+ end
42
+
43
+ def test_fail_on_too_long
44
+ assert_raise Password::LengthError do
45
+ Password.generate(Password::MAXIMUM + 1)
46
+ end
47
+ end
48
+
49
+ def test_fail_on_invalid
50
+ assert_raise Password::LengthError do
51
+ Password.generate("invalid")
52
+ end
53
+ end
54
+
55
+ def test_fail_on_invalid_path
56
+ assert_raise Password::NoWordsError do
57
+ Password.diction = "invalid/path"
58
+ end
59
+ end
60
+
61
+ def test_fail_on_nil_path
62
+ assert_raise Password::NoWordsError do
63
+ Password.diction = nil
64
+ end
65
+ end
66
+
67
+ def test_allows_non_delimiters
68
+ Password.delimiters = "#"
69
+ password = Password.generate(10, {:use_delimeter=>false})
70
+ assert_no_match /\#/, password
71
+ end
72
+
73
+ def test_allows_non_numbers
74
+ password = Password.generate(10, {:use_number=>false})
75
+ assert_no_match /\d/, password
76
+ end
77
+
78
+ def test_length_persists_without_numbers_or_delimeters
79
+ password = Password.generate(10, {:use_number=>false, :use_delimeter=>false})
80
+ assert_equal 10, password.length
81
+ end
82
+
83
+ def test_can_generate_fun
84
+ password = Password.generate_fun
85
+ assert_instance_of String, password
86
+ end
87
+
88
+
89
+ end
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: perch
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.3
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Stephen Celis, Paul Brennan
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-08-11 00:00:00.000000000Z
13
+ dependencies: []
14
+ description: A more memorable password generator. Swordfish? No, I got tired of that.
15
+ I changed it.
16
+ email: stephen@stephencelis.com
17
+ executables:
18
+ - ha-gen
19
+ extensions: []
20
+ extra_rdoc_files:
21
+ - History.rdoc
22
+ - Manifest.txt
23
+ - README.rdoc
24
+ files:
25
+ - .autotest
26
+ - History.rdoc
27
+ - Manifest.txt
28
+ - README.rdoc
29
+ - Rakefile
30
+ - bin/ha-gen
31
+ - lib/haddock.rb
32
+ - test/names.txt
33
+ - test/test_haddock.rb
34
+ homepage: http://github.com/yule/haddock
35
+ licenses: []
36
+ post_install_message:
37
+ rdoc_options:
38
+ - --main
39
+ - README.rdoc
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ requirements: []
55
+ rubyforge_project: haddock
56
+ rubygems_version: 1.8.6
57
+ signing_key:
58
+ specification_version: 3
59
+ summary: A more memorable password generator, based on haddock
60
+ test_files:
61
+ - test/test_haddock.rb