perch 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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