cipher_bureau 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.md +160 -0
- data/Rakefile +38 -0
- data/db/seeds/norwegian/wordloader.rb +47 -0
- data/lib/cipher_bureau.rb +59 -0
- data/lib/cipher_bureau/data_loader.rb +65 -0
- data/lib/cipher_bureau/dictionary.rb +63 -0
- data/lib/cipher_bureau/exceptions.rb +25 -0
- data/lib/cipher_bureau/password.rb +114 -0
- data/lib/cipher_bureau/password_meter.rb +183 -0
- data/lib/cipher_bureau/statistic.rb +48 -0
- data/lib/cipher_bureau/version.rb +3 -0
- data/lib/generators/cipher_bureau/create_migration_generator.rb +40 -0
- data/lib/generators/cipher_bureau/load_data_generator.rb +36 -0
- data/lib/generators/templates/create_cipher_bureau_dictionaries.rb +41 -0
- data/lib/generators/templates/create_cipher_bureau_statistics.rb +39 -0
- data/lib/tasks/cipher_bureau_tasks.rake +40 -0
- data/test/dummy/README.rdoc +261 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +15 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +59 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +58 -0
- data/test/dummy/db/migrate/201301290819401_create_cipher_bureau_dictionaries.rb +19 -0
- data/test/dummy/db/migrate/201301290819402_create_cipher_bureau_statistics.rb +17 -0
- data/test/dummy/db/schema.rb +46 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/fixtures/cipher_bureau_dictionaries.yml +704 -0
- data/test/fixtures/cipher_bureau_statistics.yml +40 -0
- data/test/test_helper.rb +15 -0
- data/test/units/cipher_bureau/dictionary_test.rb +74 -0
- data/test/units/cipher_bureau/password_meter_test.rb +128 -0
- data/test/units/cipher_bureau/password_test.rb +188 -0
- data/test/units/cipher_bureau/statistic_test.rb +78 -0
- data/test/units/cipher_bureau_test.rb +45 -0
- metadata +197 -0
@@ -0,0 +1,40 @@
|
|
1
|
+
noun_4_ascii:
|
2
|
+
id: 13
|
3
|
+
country_code: 47
|
4
|
+
grammar: noun
|
5
|
+
name_type:
|
6
|
+
ascii: true
|
7
|
+
length: 4
|
8
|
+
word_count: 20
|
9
|
+
noun_4:
|
10
|
+
id: 66
|
11
|
+
country_code: 47
|
12
|
+
grammar: noun
|
13
|
+
name_type:
|
14
|
+
ascii: false
|
15
|
+
length: 4
|
16
|
+
word_count: 20
|
17
|
+
surname_5:
|
18
|
+
id: 308
|
19
|
+
country_code: 47
|
20
|
+
grammar: name
|
21
|
+
name_type: surname
|
22
|
+
ascii: false
|
23
|
+
length: 5
|
24
|
+
word_count: 20
|
25
|
+
boysname_5:
|
26
|
+
id: 320
|
27
|
+
country_code: 47
|
28
|
+
grammar: name
|
29
|
+
name_type: boysname
|
30
|
+
ascii: false
|
31
|
+
length: 5
|
32
|
+
word_count: 20
|
33
|
+
girlsname_5:
|
34
|
+
id: 332
|
35
|
+
country_code: 47
|
36
|
+
grammar: name
|
37
|
+
name_type: girlsname
|
38
|
+
ascii: false
|
39
|
+
length: 5
|
40
|
+
word_count: 20
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# Configure Rails Environment
|
2
|
+
ENV["RAILS_ENV"] = "test"
|
3
|
+
|
4
|
+
require File.expand_path("../dummy/config/environment.rb", __FILE__)
|
5
|
+
require "rails/test_help"
|
6
|
+
|
7
|
+
Rails.backtrace_cleaner.remove_silencers!
|
8
|
+
|
9
|
+
# Load support files
|
10
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
11
|
+
|
12
|
+
# Load fixtures from the engine
|
13
|
+
if ActiveSupport::TestCase.method_defined?(:fixture_path=)
|
14
|
+
ActiveSupport::TestCase.fixture_path = File.expand_path("../fixtures", __FILE__)
|
15
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# Copyright (c) 2013 Dynamic Project Management AS
|
3
|
+
# Copyright (c) 2013 Knut I. Stenmark
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
# a copy of this software and associated documentation files (the
|
7
|
+
# "Software"), to deal in the Software without restriction, including
|
8
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
# the following conditions:
|
12
|
+
#
|
13
|
+
# The above copyright notice and this permission notice shall be
|
14
|
+
# included in all copies or substantial portions of the Software.
|
15
|
+
#
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
23
|
+
|
24
|
+
require 'test_helper'
|
25
|
+
|
26
|
+
class CipherBureau::DictionaryTest < ActiveSupport::TestCase
|
27
|
+
fixtures :all
|
28
|
+
|
29
|
+
context 'validation' do
|
30
|
+
should validate_presence_of :word
|
31
|
+
should validate_presence_of :grammar
|
32
|
+
should validate_presence_of :country_code
|
33
|
+
end
|
34
|
+
context 'saving' do
|
35
|
+
setup do
|
36
|
+
@word = CipherBureau::Dictionary.new :word => 'gurba', :grammar => 'bullshit', :country_code => '999'
|
37
|
+
end
|
38
|
+
should 'be valid' do
|
39
|
+
assert @word.valid?, "Test record was invalid"
|
40
|
+
end
|
41
|
+
should 'set length' do
|
42
|
+
@word.save!
|
43
|
+
assert_equal 5, @word.length
|
44
|
+
end
|
45
|
+
should 'set ascii' do
|
46
|
+
@word.word = 'heihåpp'
|
47
|
+
@word.save!
|
48
|
+
assert !@word.ascii
|
49
|
+
end
|
50
|
+
should 'register statistics' do
|
51
|
+
CipherBureau::Statistic.expects(:register).with(@word)
|
52
|
+
@word.save
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'class method' do
|
57
|
+
context 'random' do
|
58
|
+
should 'check statistics before fetching data' do
|
59
|
+
criteria = {:country_code => 47, :grammar => 'noun'}
|
60
|
+
CipherBureau::Statistic.expects(:word_count).with(criteria.merge(:length => 4)).returns(3)
|
61
|
+
CipherBureau::Dictionary.expects(:randomized_offset).with(3).returns(1)
|
62
|
+
assert_equal 'kjel', CipherBureau::Dictionary.random(4, criteria)
|
63
|
+
end
|
64
|
+
should 'support camelize' do
|
65
|
+
CipherBureau::Dictionary.expects(:fetch_random_word).with(:length => 4).returns(stub(:word => 'halo'))
|
66
|
+
assert_equal 'Halo', CipherBureau::Dictionary.random(4, :camelize => true)
|
67
|
+
CipherBureau::Dictionary.expects(:fetch_random_word).with(:length => 4).returns(stub(:word => 'øyne'))
|
68
|
+
assert_equal 'Øyne', CipherBureau::Dictionary.random(4, :camelize => true)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
# Copyright (c) 2013 Dynamic Project Management AS
|
2
|
+
# Copyright (c) 2013 Knut I. Stenmark
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
|
23
|
+
# encoding: utf-8
|
24
|
+
require 'test_helper'
|
25
|
+
|
26
|
+
class CipherBureau::PasswordMeterTest < ActiveSupport::TestCase
|
27
|
+
# Algorihm:
|
28
|
+
# See http://www.passwordmeter.com
|
29
|
+
setup do
|
30
|
+
@m = CipherBureau::PasswordMeter.new('12345678')
|
31
|
+
end
|
32
|
+
|
33
|
+
def t(method, expected, password = nil)
|
34
|
+
@m.password = password if password
|
35
|
+
actual = @m.send(method)
|
36
|
+
assert_equal expected, actual, "Method: #{method} with password '#{@m.password}' expected to return #{expected}, was #{actual}"
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'strength' do
|
40
|
+
should 'calculate weak' do
|
41
|
+
@m.password = 'aaaaaaaaaaaa'
|
42
|
+
assert_equal 48 - 12 - 124 - 22, @m.absolute_score
|
43
|
+
assert_equal 0, @m.strength
|
44
|
+
end
|
45
|
+
should 'calculate strong' do
|
46
|
+
@m.password = 'acgHY79-|/'
|
47
|
+
assert_equal 40 + 16 + 14 + 8 + 18 + 8 + 10 - 2 - 4 - 2, @m.absolute_score
|
48
|
+
assert_equal 100, @m.strength
|
49
|
+
end
|
50
|
+
should 'also be a class method' do
|
51
|
+
assert_equal 100, CipherBureau::PasswordMeter.strength( 'acgHY79-|/')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
context 'addition' do
|
57
|
+
should 'return the expected results' do
|
58
|
+
t :number_of_characters, 8 * 4
|
59
|
+
t :uppercase_letters, (7 - 3 ) * 2, 'AbCdefG'
|
60
|
+
t :uppercase_letters, 0, 'aaaaaaaaaaa'
|
61
|
+
t :lowercase_letters, (7 - 4) * 2, 'AbCdefG'
|
62
|
+
t :lowercase_letters, 0, 'aaaaaaaaaaa'
|
63
|
+
t :lowercase_letters, 2, 'aaaaaaaaaaA'
|
64
|
+
t :numbers, 0, '12345678'
|
65
|
+
t :numbers, 8 * 4, 'a12345678'
|
66
|
+
t :symbols, 3 * 6, 'abcdef[]|'
|
67
|
+
t :middle_numbers_or_symbols, 0, '11'
|
68
|
+
t :middle_numbers_or_symbols, 2 * 2, 'ab12a'
|
69
|
+
t :middle_numbers_or_symbols, 2 * 2, 'ab[]a'
|
70
|
+
t :middle_numbers_or_symbols, 2 * 4, 'ab[12]a'
|
71
|
+
t :requirements, 0, '12'
|
72
|
+
t :requirements, 0, 'abcdefghi'
|
73
|
+
t :requirements, 0, 'abcde1234'
|
74
|
+
t :requirements, 0, 'abcde[]&:'
|
75
|
+
t :requirements, 10, 'AbB=-123i'
|
76
|
+
t :requirements, 8, 'AbB12345'
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'deduction' do
|
81
|
+
should 'return representative values for letters only' do
|
82
|
+
t :letters_only, 5, 'abcde'
|
83
|
+
t :letters_only, 5, 'ABCDE'
|
84
|
+
t :letters_only, 5, 'AbCdE'
|
85
|
+
t :letters_only, 0, 'AbCd1'
|
86
|
+
t :letters_only, 0, '12345'
|
87
|
+
t :letters_only, 0, 'AbCd['
|
88
|
+
t :letters_only, 0, ';:`?=)'
|
89
|
+
end
|
90
|
+
should 'return representative values for numbers only' do
|
91
|
+
t :numbers_only, 5, '54321'
|
92
|
+
t :numbers_only, 0, '5432a'
|
93
|
+
t :numbers_only, 0, ';:`?=)'
|
94
|
+
t :numbers_only, 0, 'ABCDE'
|
95
|
+
end
|
96
|
+
should 'return representative values for repeated_characters' do
|
97
|
+
t :repeated_characters, 37, '11111'
|
98
|
+
t :repeated_characters, 15, '11211'
|
99
|
+
t :repeated_characters, 3, 'aa2b1'
|
100
|
+
end
|
101
|
+
should 'return representative values for sequential_letters' do
|
102
|
+
t :sequential_letters, 3, 'ABC'
|
103
|
+
t :sequential_letters, 3, 'BCD'
|
104
|
+
t :sequential_letters, 6, 'ABCD'
|
105
|
+
t :sequential_letters, 6, 'DCBA'
|
106
|
+
end
|
107
|
+
should 'return representative values for sequential_numbers' do
|
108
|
+
t :sequential_numbers, 6, '1234'
|
109
|
+
t :sequential_numbers, 6, '4321'
|
110
|
+
t :sequential_numbers, 9, '54321'
|
111
|
+
end
|
112
|
+
should 'return representative values for sequential_symbols' do
|
113
|
+
t :sequential_symbols, 21, '!@#$%^&*()'
|
114
|
+
end
|
115
|
+
should 'return representative values for consecutive_uppercase' do
|
116
|
+
t :consecutive_uppercase, 6, 'ACEG'
|
117
|
+
t :consecutive_uppercase, 12, 'ACEGsKJSNks'
|
118
|
+
end
|
119
|
+
should 'return representative values for consecutive_lowercase' do
|
120
|
+
t :consecutive_lowercase, 6, 'aceg'
|
121
|
+
t :consecutive_lowercase, 10, 'acegABkjjJ'
|
122
|
+
end
|
123
|
+
should 'return representative values for consecutive_numbers' do
|
124
|
+
t :consecutive_numbers, 6, '1357'
|
125
|
+
t :consecutive_numbers, 8, 'ab10357CD'
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,188 @@
|
|
1
|
+
# Copyright (c) 2013 Dynamic Project Management AS
|
2
|
+
# Copyright (c) 2013 Knut I. Stenmark
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
|
23
|
+
# encoding: utf-8
|
24
|
+
require 'test_helper'
|
25
|
+
|
26
|
+
class CipherBureau::PasswordTest < ActiveSupport::TestCase
|
27
|
+
fixtures :all
|
28
|
+
|
29
|
+
setup do
|
30
|
+
CipherBureau.default_memorable_options = {}
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'the interface' do
|
34
|
+
context 'memorable' do
|
35
|
+
should 'generate correct length' do
|
36
|
+
@pwd = CipherBureau::Password.memorable(:length => 10)
|
37
|
+
assert_equal 10, @pwd.length
|
38
|
+
end
|
39
|
+
should 'have a default option' do
|
40
|
+
end
|
41
|
+
should 'support grammar selection' do
|
42
|
+
@pwd = CipherBureau::Password.memorable(:length => 10)
|
43
|
+
@meter = CipherBureau::PasswordMeter.new(@pwd)
|
44
|
+
end
|
45
|
+
should 'support camelize option' do
|
46
|
+
@pwd = CipherBureau::Password.memorable(:length => 10, :camelize => true)
|
47
|
+
assert_equal @pwd[0].upcase, @pwd[0]
|
48
|
+
assert_equal @pwd[6].upcase, @pwd[6]
|
49
|
+
end
|
50
|
+
should 'support middle_numbers option' do
|
51
|
+
CipherBureau::Dictionary.expects(:random).twice.with(4, {}).returns('abcd','efgh')
|
52
|
+
@pwd = CipherBureau::Password.memorable(:length => 10, :middle_numbers => true)
|
53
|
+
assert @pwd.match( /^\w{4,4}\d{2,2}\w{4,4}$/)
|
54
|
+
end
|
55
|
+
should 'embed numbers and symbols in middle' do
|
56
|
+
@pwd = CipherBureau::Password.memorable(:length => 10)
|
57
|
+
@meter = CipherBureau::PasswordMeter.new(@pwd)
|
58
|
+
assert @meter.middle_numbers_or_symbols > 2
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'scope' do
|
62
|
+
context 'with default values' do
|
63
|
+
setup do
|
64
|
+
CipherBureau.default_memorable_options = {
|
65
|
+
:length => 10,
|
66
|
+
:country_code => 47,
|
67
|
+
:ascii => false,
|
68
|
+
:grammar => 'name',
|
69
|
+
:name_type => 'girlsname'
|
70
|
+
}
|
71
|
+
end
|
72
|
+
should 'initialize with them' do
|
73
|
+
@pwd = CipherBureau::Password.new :length => 10
|
74
|
+
assert_equal ({:country_code => 47, :ascii => false, :grammar => 'name', :name_type => 'girlsname'}), @pwd.send(:scope)
|
75
|
+
end
|
76
|
+
should 'override, by setting initializer' do
|
77
|
+
opts = {:length => 8, :country_code => 44, :ascii => true, :grammar => 'noun'}
|
78
|
+
@pwd = CipherBureau::Password.new opts
|
79
|
+
opts.delete(:length)
|
80
|
+
assert_equal opts, @pwd.send(:scope)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
context 'letters_and_numbers' do
|
86
|
+
should 'contain only letters and numbers' do
|
87
|
+
10.times do
|
88
|
+
assert_match /^[A-Za-z0-9]{12,12}$/, CipherBureau::Password.letters_and_numbers(:length => 12)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
context 'numbers_only' do
|
93
|
+
should 'contain only numbers only' do
|
94
|
+
10.times do
|
95
|
+
assert_match /^[0-9]{10,10}$/, CipherBureau::Password.numbers_only(:length => 10)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
context 'random' do
|
100
|
+
should 'contain any random character' do
|
101
|
+
50.times do
|
102
|
+
illegal = CipherBureau::Password.random(1, :length => 12).bytes.select { |b| b < 32 || b > 126 }
|
103
|
+
assert_equal 0, illegal.size
|
104
|
+
end
|
105
|
+
end
|
106
|
+
should 'generate the correct length' do
|
107
|
+
pwd = CipherBureau::Password.random(1, :length => 14)
|
108
|
+
assert_equal 14, pwd.length
|
109
|
+
end
|
110
|
+
should 'really be random' do
|
111
|
+
assert_not_equal CipherBureau::Password.random(1, :length => 14), CipherBureau::Password.random(1, :length => 14)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
context 'fips-181' do
|
115
|
+
# http://www.itl.nist.gov/fipspubs/fip181.htm
|
116
|
+
should 'never be used' do
|
117
|
+
assert_raises NoMethodError do
|
118
|
+
pwd = CipherBureau::Password.fips_181(1, :length => 14)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
context 'strength' do
|
123
|
+
should 'delegate to PasswordMeter' do
|
124
|
+
CipherBureau::PasswordMeter.expects(:strength).with('abcde').returns(1)
|
125
|
+
assert_equal 1, CipherBureau::Password.strength('abcde')
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context 'initializing' do
|
131
|
+
should 'validate length' do
|
132
|
+
assert_raises ArgumentError do
|
133
|
+
pwd = CipherBureau::Password.new
|
134
|
+
end
|
135
|
+
end
|
136
|
+
should 'set options' do
|
137
|
+
pwd = CipherBureau::Password.new({:length => 12, :country_code => 99})
|
138
|
+
assert_equal 12, pwd.length
|
139
|
+
assert_equal ({:country_code => 99}), pwd.options
|
140
|
+
end
|
141
|
+
should 'set defaults' do
|
142
|
+
CipherBureau.default_memorable_options = {
|
143
|
+
:length => 12,
|
144
|
+
:country_code => 98
|
145
|
+
}
|
146
|
+
pwd = CipherBureau::Password.new
|
147
|
+
assert_equal 12, pwd.length
|
148
|
+
assert_equal ({:country_code => 98}), pwd.options
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
context 'collecting and enumerating' do
|
153
|
+
context 'single record' do
|
154
|
+
should 'return sigle object' do
|
155
|
+
assert CipherBureau::Password.random(1, :length => 10).is_a?(String)
|
156
|
+
assert CipherBureau::Password.random(:length => 10).is_a?(String)
|
157
|
+
end
|
158
|
+
should 'have the abilty to include strength' do
|
159
|
+
assert CipherBureau::Password.random(:length => 10, :strength => true).is_a?(Array)
|
160
|
+
CipherBureau::Password.expects(:strength).returns(10)
|
161
|
+
CipherBureau::Password.any_instance.expects(:random).returns('abcdefgh')
|
162
|
+
assert_equal ['abcdefgh', 10], CipherBureau::Password.random(:length => 10, :strength => true)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
context 'multiple records' do
|
166
|
+
should 'return array' do
|
167
|
+
assert CipherBureau::Password.random(2, :length => 10).is_a?(Array)
|
168
|
+
assert_equal 2, CipherBureau::Password.random(2, :length => 10).size
|
169
|
+
assert_equal 3, CipherBureau::Password.random(3, :length => 10).size
|
170
|
+
end
|
171
|
+
should 'have the abilty to include strength' do
|
172
|
+
CipherBureau::Password.expects(:strength).twice.returns(10, 5)
|
173
|
+
CipherBureau::Password.any_instance.expects(:random).twice.returns('abcdefgh', 'jklmno')
|
174
|
+
assert_equal [['abcdefgh', 10], ['jklmno', 5]], CipherBureau::Password.random(2, :length => 10, :strength => true)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
context 'hash option' do
|
178
|
+
should 'return hash' do
|
179
|
+
assert CipherBureau::Password.random(:length => 10, :strength => true).is_a?(Array)
|
180
|
+
CipherBureau::Password.stubs(:strength).returns(10)
|
181
|
+
CipherBureau::Password.any_instance.stubs(:random).returns('abcdefgh')
|
182
|
+
expected = {:password => 'abcdefgh', :strength => 10}
|
183
|
+
assert_equal expected, CipherBureau::Password.random(:length => 10, :strength => true, :as => :hash)
|
184
|
+
assert_equal [expected, expected], CipherBureau::Password.random(2, :length => 10, :strength => true, :as => :hash)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|