oro 1.0.0.2

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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d0380ef86c093d775e831662d68f3704eefef9c8
4
+ data.tar.gz: 6045e214724254cfc7909ade545dea77bda2e2d4
5
+ SHA512:
6
+ metadata.gz: 62361ea62f0e5664aec526025ac35bb20bf4e904958d2a923c1400bf27f55b04eeea7c3c426195c8dd182c92bf45a25afc26177c5a7f4c1ee652ce3d203cb281
7
+ data.tar.gz: 7cf0c7bb8cd3377235b86d5912878bb3c0d2643fa149fcf05ff9306ca04e135fbcf4e312af47c29b18ec43c9bcc6cee98c0c384a5287cfb50e29f6d338e99458
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Joel Wagener
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.
@@ -0,0 +1,72 @@
1
+ # Oro
2
+
3
+ _**"The enemy knows the system"** ([Claude Shannon](http://en.wikipedia.org/wiki/Claude_Shannon) / [Auguste Kerckhoffs](http://en.wikipedia.org/wiki/Auguste_Kerckhoffs))_
4
+
5
+ A flexible, command-line utility which generates memorable passwords.
6
+
7
+ ## Usage
8
+
9
+ Usage: oro [settings]
10
+
11
+ Part settings (all lengths optional)
12
+ p[n] Punctuation part
13
+ n[n] Number part
14
+ l[n] Linnaeus part
15
+ a[n] Latin part
16
+ g[n] German part
17
+ e[n] English part
18
+ m[n] Emoticon part
19
+ b[n] Braille part
20
+
21
+ Config settings
22
+ -i, --iterations=MANDATORY The number of passwords to generate
23
+ -c, --[no-]capitalize Capitalize every word part
24
+ -r, --[no-]capitalize-random Randomly capitalize one letter in every word part
25
+ -l, --[no-]l33t Make one l33t-style replacement per word part
26
+ -s, --[no-]shuffle Randomize map parts
27
+ -f, --format=MANDATORY Results format: string, json, yaml
28
+ -e, --separator[=OPTIONAL] Separator characters
29
+
30
+ Action settings
31
+ --lists Show all available lists
32
+ --prefs, --preferences Show your current preferences
33
+ --defaults Show system defaults
34
+ --set Set passed settings as your preferences
35
+ --reset Reset your preferences to system defaults
36
+ -v, --verbose Provide verbose feedback, dictionary metadata, and statistics when run
37
+ -h, --help Print this dialog
38
+ --version Show version
39
+
40
+ Examples
41
+ oro e9 p1 n3 -s --set
42
+ oro n4 -e"-" -i4
43
+ oro n99 -i10
44
+ oro e10 n5 -fjson
45
+
46
+ See dictionary source files for associated license attributions.
47
+
48
+ ## License
49
+
50
+ http://opensource.org/licenses/mit-license.php
51
+
52
+ The MIT License (MIT)
53
+
54
+ Copyright (c) 2015 Joel Wagener
55
+
56
+ Permission is hereby granted, free of charge, to any person obtaining a copy
57
+ of this software and associated documentation files (the "Software"), to deal
58
+ in the Software without restriction, including without limitation the rights
59
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
60
+ copies of the Software, and to permit persons to whom the Software is
61
+ furnished to do so, subject to the following conditions:
62
+
63
+ The above copyright notice and this permission notice shall be included in
64
+ all copies or substantial portions of the Software.
65
+
66
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
67
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
68
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
69
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
70
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
71
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
72
+ THE SOFTWARE.
@@ -0,0 +1,19 @@
1
+ require 'rake/testtask'
2
+
3
+ namespace :oro do
4
+
5
+ Rake::TestTask.new do |task|
6
+ Dir.glob(File.dirname(File.absolute_path(__FILE__)) + 'lib/oro/*.rb') {|file| require file} # FIXME Seemingly fails to load shit.
7
+ task.libs << 'lib/oro/*.rb' # FIXME Have no idea if this is doing anything.
8
+ task.test_files = FileList['test/*_test.rb']
9
+ task.verbose = true
10
+ end
11
+
12
+ desc 'Say Hola!'
13
+ task :hola do
14
+ puts 'Hola, Señora!'
15
+ end
16
+
17
+ end
18
+
19
+ task :default => 'oro:test'
data/bin/oro ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/oro'
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'benchmark'
4
+ require 'yaml'
5
+ require 'json'
6
+ # require 'byebug'
7
+ require_relative 'oro/settings'
8
+ require_relative 'oro/password'
9
+
10
+ # LET'S make passwords
11
+
12
+ time = Benchmark.measure do
13
+ begin
14
+
15
+ # Create ~/.oro preferences file if missing
16
+ Preferences.instance
17
+
18
+ # Set settings, parse clio
19
+ password = Password.new(ARGV)
20
+
21
+ # Manage actions here (and retain single responsibility principle for SettingsParser)
22
+ password.actions.each_pair do |action, val|
23
+ case action
24
+ when :lists
25
+ puts Password.installed_parts_summary
26
+ exit
27
+ when :preferences
28
+ puts Preferences.instance.clio
29
+ exit
30
+ when :defaults
31
+ puts Defaults.instance.clio
32
+ exit
33
+ when :set
34
+ Preferences.instance.settings = password.virgin_settings
35
+ puts "Saved preferences\n#{Preferences.instance.clio}"
36
+ when :reset
37
+ Preferences.instance.reset_defaults
38
+ puts "Reset preferences to defaults\n#{Preferences.instance.clio}"
39
+ exit
40
+ when :verbose
41
+ $VERBOSE = true
42
+ when :help
43
+ puts val
44
+ exit
45
+ when :version
46
+ puts val
47
+ exit
48
+ end
49
+ end
50
+
51
+ # Be verbose if requested
52
+ warn(Preferences.instance.to_s, "Merged settings: #{ClioHelper.clioize(password.settings)}", "Password lengths will be: #{password.length}") if $VERBOSE
53
+
54
+ @passwords = []
55
+ time_passwords = Benchmark.measure do
56
+ (1..password.config[:iterations]).each { @passwords << password.result }
57
+ end
58
+
59
+ warn("Time to generate #{password.config[:iterations]} passwords: #{time_passwords.real}, #{time_passwords.real / password.config[:iterations]} per password") if $VERBOSE
60
+
61
+ # We are done
62
+ case password.config[:format]
63
+ when 'json'
64
+ @passwords = @passwords.to_json
65
+ when 'yaml', 'yml'
66
+ @passwords = @passwords.to_yaml
67
+ when 'string'
68
+ @passwords = @passwords.join(password.config[:separator]).strip
69
+ end
70
+
71
+ rescue OptionParser::InvalidOption, OptionParser::AmbiguousOption, OptionParser::MissingArgument, OptionParser::InvalidArgument => e
72
+ puts "Error: #{e.message}"
73
+ rescue NoMatchingListError, ListIsNonContiguousError, MatchlessLengthWordError => e
74
+ puts e.message
75
+ end
76
+ end # end Benchmark
77
+
78
+ # Return results
79
+ warn("Time to run: #{time.real}") if $VERBOSE
80
+ puts @passwords
@@ -0,0 +1,19 @@
1
+ --- !ruby/object:OpenStruct
2
+ table:
3
+ :plan:
4
+ - - English
5
+ - 8
6
+ - - Punctuation
7
+ - 1
8
+ - - Number
9
+ - 3
10
+ :config:
11
+ :iterations: 5
12
+ :capitalize: true
13
+ :capitalize_random: false
14
+ :l33t: false
15
+ :shuffle: false
16
+ :format: 'string'
17
+ :separator: "\n" # Requires double quotes
18
+
19
+ modifiable: true
@@ -0,0 +1,18 @@
1
+ # Oro error classes
2
+ class OroError < Exception
3
+ def initialize(msg)
4
+ @msg = msg
5
+ end
6
+
7
+ def message
8
+ "Error: #{@msg}"
9
+ end
10
+ end
11
+
12
+ class PartInstantiationError < OroError; end
13
+
14
+ class MatchlessLengthWordError < OroError; end
15
+
16
+ class NoMatchingListError < OroError; end
17
+
18
+ class ListIsNonContiguousError < OroError; end
@@ -0,0 +1,62 @@
1
+ # Rails-style string helpers
2
+ module Helpers
3
+ refine String do
4
+ def camelize
5
+ dup.split(/_/).map(&:capitalize).join('') # Modified from: http://yehudakatz.com/2010/11/30/ruby-2-0-refinements-in-practice/
6
+ end
7
+
8
+ # Not presently used
9
+ def underscore
10
+ gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').gsub(/([a-z\d])([A-Z])/, '\1_\2').tr('-', '_').downcase
11
+ end
12
+ end
13
+ end
14
+
15
+ # Mixed in to the singleton Defaults and Preference classes, and the Password class
16
+ module SettingsAccessors
17
+ def plan
18
+ settings.plan
19
+ end
20
+
21
+ def plan=(val)
22
+ @settings.plan = val
23
+ end
24
+
25
+ def config
26
+ settings.config
27
+ end
28
+
29
+ def config=(val)
30
+ @settings.config = val
31
+ end
32
+
33
+ def actions
34
+ settings.actions
35
+ end
36
+
37
+ def actions=(val)
38
+ @settings.actions = val
39
+ end
40
+ end
41
+
42
+ # Helper methods for turning settings back into clio
43
+ # FIXME: This *helper* method requires knowledge of the Password class
44
+ module ClioHelper
45
+ def self.clioize(settings)
46
+ clio = []
47
+ settings.plan.each { |part| Password.installed_part_switches.include?(part[0]) ? clio << "w#{part[1]}" : clio << "#{part[0][0].downcase}#{part[1]}" }
48
+ settings.config.each { |part| clio << "--#{part[0].to_s.gsub('_', '-')}=#{part[1].to_s.gsub(/\n|\t|\r/, "\n" => '"\n"', "\t" => '"\t"', "\r" => '"\r"')}" }
49
+ clio.join(' ')
50
+ end
51
+
52
+ def clio
53
+ ClioHelper.clioize(settings)
54
+ end
55
+ end
56
+
57
+ # Custom inspection
58
+ module SettingsInspector
59
+ def to_s
60
+ "#{self.class.name}: #{self.clio} (#{self.class::FILE})"
61
+ end
62
+ end
@@ -0,0 +1,128 @@
1
+ # Class representing a password plan part, which map to installed psrt lists
2
+ class Part
3
+ LEET = { 'a' => ['@'], 'b' => ['|3'], 'd' => ['|)'], 'e' => ['3'], 'f' => ['ph'], 'i' => ['|'], 'k' => ['|<'],
4
+ 'l' => ['|_'], 'o' => ['0'], 'p' => ['|*'], 's' => ['$', '5'], 'w' => ["'//"] }
5
+
6
+ def self.list_location
7
+ @list_location
8
+ end
9
+
10
+ def self.list_location=(location)
11
+ @list_location = location
12
+ end
13
+
14
+ # instance_exec (vs. instance_eval) to pass params, define_singleton_method to add the class method
15
+ def self.listify
16
+ list = YAML.load_file(@list_location)
17
+ instance_exec(list) { |l| define_singleton_method('list') { @list ||= l } }
18
+ self.respond_to?(:list) ? true : false
19
+ end
20
+
21
+ def self.single_character_list?
22
+ (shortest == 1 && longest == 1) ? true : false
23
+ end
24
+
25
+ def self.count
26
+ list.size
27
+ end
28
+
29
+ def self.shortest
30
+ @shortest ||= list.empty? ? 0 : list.min { |a, b| a.length <=> b.length }.length
31
+ end
32
+
33
+ def self.longest
34
+ @longest ||= list.empty? ? 0 : list.max { |a, b| a.length <=> b.length }.length
35
+ end
36
+
37
+ def self.middle
38
+ (shortest + longest) / 2
39
+ end
40
+
41
+ def self.distinct?
42
+ list.size == list.uniq.size ? true : false
43
+ end
44
+
45
+ def self.descendants
46
+ ObjectSpace.each_object(Class).select { |klass| klass < self }
47
+ end
48
+
49
+ def self.contiguous?
50
+ absences.empty?
51
+ end
52
+
53
+ def self.absences
54
+ length_exists = proc { |length| list.select { |w| w.length == length }.empty? ? false : true }
55
+ lengths = []
56
+ (shortest..longest).each do |len|
57
+ lengths << len if !length_exists.call(len)
58
+ end
59
+ lengths
60
+ end
61
+
62
+ def self.get_one
63
+ list.sample
64
+ end
65
+
66
+ def self.get(size, config = {})
67
+ single_character_list? ? get_for_single_character_part(size) : get_for_word_part(size, config)
68
+ end
69
+
70
+ def self.get_for_single_character_part(size)
71
+ result = []
72
+ size.times { result << get_one }
73
+ result.join
74
+ end
75
+
76
+ def self.get_for_word_part(size, config = {})
77
+ fail MatchlessLengthWordError, "Matchless length of #{size} requested from:\n#{self}" if size < shortest || size > longest
78
+
79
+ # FIXME: The performance benefit of refactoring to use Array#reject, or possibly reject!, should be tested.
80
+ get_proc, attempt = proc { get_one }, ''
81
+
82
+ until attempt.length == size do attempt = get_proc.call end
83
+
84
+ attempt.capitalize! if config[:capitalize]
85
+
86
+ if config[:capitalize_random]
87
+ temp = attempt.chars
88
+ temp[rand(temp.length)].upcase!
89
+ attempt = temp.join
90
+ end
91
+
92
+ # An index histogram of matching leetables; ex: {"a"=>[9], "e"=>[0, 6], "i"=>[8]}
93
+ if config[:l33t]
94
+ leetables = {}
95
+ LEET.keys.each do |l|
96
+ matches = (0...attempt.length).find_all { |i| attempt[i, 1] == l }
97
+ leetables[l] = matches unless matches.empty?
98
+ end
99
+
100
+ unless leetables.empty?
101
+ leeted = leetables.to_a.sample(1).flatten.first # Get a random key from the histogram
102
+ attempt.sub!(leeted, LEET[leeted][rand(LEET[leeted].length)]) # Change to gsub to replace all matches
103
+ end
104
+ end
105
+ attempt
106
+ end
107
+
108
+ def self.to_s
109
+ "List #{name} > count:#{count}, shortest:#{shortest}, longest:#{longest}, middle:#{middle}, distinct:#{distinct?}, get one:'#{get_one}', contiguous:#{contiguous?}" + (absences.empty? ? '' : ", absences:#{absences}")
110
+ end
111
+ end
112
+
113
+ # Initialize list-less parts classes from all installed <list>.yml files, * at load time *
114
+ begin
115
+ require_relative 'helpers'
116
+ using Helpers
117
+
118
+ PARTS_DIRECTORY = 'parts'
119
+
120
+ Dir.glob(File.join(File.dirname(__FILE__), PARTS_DIRECTORY, '**', '*.yml')) do |list|
121
+ klass_name = File.basename(list, '.yml').camelize
122
+ instantiated = Object.const_set(klass_name, Class.new(Part)) # Creates subclasses of Part
123
+ instantiated.list_location = list
124
+ end
125
+
126
+ rescue PartInstantiationError => e
127
+ puts e.message
128
+ end # End part class initilization
@@ -0,0 +1,259 @@
1
+ # http://unicodeemoticons.com/symbols_all.htm ; Unknown license ; Formatting.
2
+
3
+ ---
4
+ - ⠁
5
+ - ⠂
6
+ - ⠃
7
+ - ⠄
8
+ - ⠅
9
+ - ⠆
10
+ - ⠇
11
+ - ⠈
12
+ - ⠉
13
+ - ⠊
14
+ - ⠋
15
+ - ⠌
16
+ - ⠍
17
+ - ⠎
18
+ - ⠏
19
+ - ⠐
20
+ - ⠑
21
+ - ⠒
22
+ - ⠓
23
+ - ⠔
24
+ - ⠕
25
+ - ⠖
26
+ - ⠗
27
+ - ⠘
28
+ - ⠙
29
+ - ⠚
30
+ - ⠛
31
+ - ⠜
32
+ - ⠝
33
+ - ⠞
34
+ - ⠟
35
+ - ⠠
36
+ - ⠡
37
+ - ⠢
38
+ - ⠣
39
+ - ⠤
40
+ - ⠥
41
+ - ⠦
42
+ - ⠧
43
+ - ⠨
44
+ - ⠩
45
+ - ⠪
46
+ - ⠫
47
+ - ⠬
48
+ - ⠭
49
+ - ⠮
50
+ - ⠯
51
+ - ⠰
52
+ - ⠱
53
+ - ⠲
54
+ - ⠳
55
+ - ⠴
56
+ - ⠵
57
+ - ⠶
58
+ - ⠷
59
+ - ⠸
60
+ - ⠹
61
+ - ⠺
62
+ - ⠻
63
+ - ⠼
64
+ - ⠽
65
+ - ⠾
66
+ - ⠿
67
+ - ⡀
68
+ - ⡁
69
+ - ⡂
70
+ - ⡃
71
+ - ⡄
72
+ - ⡅
73
+ - ⡆
74
+ - ⡇
75
+ - ⡈
76
+ - ⡉
77
+ - ⡊
78
+ - ⡋
79
+ - ⡌
80
+ - ⡍
81
+ - ⡎
82
+ - ⡏
83
+ - ⡐
84
+ - ⡑
85
+ - ⡒
86
+ - ⡓
87
+ - ⡔
88
+ - ⡕
89
+ - ⡖
90
+ - ⡗
91
+ - ⡘
92
+ - ⡙
93
+ - ⡚
94
+ - ⡛
95
+ - ⡜
96
+ - ⡝
97
+ - ⡞
98
+ - ⡟
99
+ - ⡠
100
+ - ⡡
101
+ - ⡢
102
+ - ⡣
103
+ - ⡤
104
+ - ⡥
105
+ - ⡦
106
+ - ⡧
107
+ - ⡨
108
+ - ⡩
109
+ - ⡪
110
+ - ⡫
111
+ - ⡬
112
+ - ⡭
113
+ - ⡮
114
+ - ⡯
115
+ - ⡰
116
+ - ⡱
117
+ - ⡲
118
+ - ⡳
119
+ - ⡴
120
+ - ⡵
121
+ - ⡶
122
+ - ⡷
123
+ - ⡸
124
+ - ⡹
125
+ - ⡺
126
+ - ⡻
127
+ - ⡼
128
+ - ⡽
129
+ - ⡾
130
+ - ⡿
131
+ - ⢀
132
+ - ⢁
133
+ - ⢂
134
+ - ⢃
135
+ - ⢄
136
+ - ⢅
137
+ - ⢆
138
+ - ⢇
139
+ - ⢈
140
+ - ⢉
141
+ - ⢊
142
+ - ⢋
143
+ - ⢌
144
+ - ⢍
145
+ - ⢎
146
+ - ⢏
147
+ - ⢐
148
+ - ⢑
149
+ - ⢒
150
+ - ⢓
151
+ - ⢔
152
+ - ⢕
153
+ - ⢖
154
+ - ⢗
155
+ - ⢘
156
+ - ⢙
157
+ - ⢚
158
+ - ⢛
159
+ - ⢜
160
+ - ⢝
161
+ - ⢞
162
+ - ⢟
163
+ - ⢠
164
+ - ⢡
165
+ - ⢢
166
+ - ⢣
167
+ - ⢤
168
+ - ⢥
169
+ - ⢦
170
+ - ⢧
171
+ - ⢨
172
+ - ⢩
173
+ - ⢪
174
+ - ⢫
175
+ - ⢬
176
+ - ⢭
177
+ - ⢮
178
+ - ⢯
179
+ - ⢰
180
+ - ⢱
181
+ - ⢲
182
+ - ⢳
183
+ - ⢴
184
+ - ⢵
185
+ - ⢶
186
+ - ⢷
187
+ - ⢸
188
+ - ⢹
189
+ - ⢺
190
+ - ⢻
191
+ - ⢼
192
+ - ⢽
193
+ - ⢾
194
+ - ⢿
195
+ - ⣀
196
+ - ⣁
197
+ - ⣂
198
+ - ⣃
199
+ - ⣄
200
+ - ⣅
201
+ - ⣆
202
+ - ⣇
203
+ - ⣈
204
+ - ⣉
205
+ - ⣊
206
+ - ⣋
207
+ - ⣌
208
+ - ⣍
209
+ - ⣎
210
+ - ⣏
211
+ - ⣐
212
+ - ⣑
213
+ - ⣒
214
+ - ⣓
215
+ - ⣔
216
+ - ⣕
217
+ - ⣖
218
+ - ⣗
219
+ - ⣘
220
+ - ⣙
221
+ - ⣚
222
+ - ⣛
223
+ - ⣜
224
+ - ⣝
225
+ - ⣞
226
+ - ⣟
227
+ - ⣠
228
+ - ⣡
229
+ - ⣢
230
+ - ⣣
231
+ - ⣤
232
+ - ⣥
233
+ - ⣦
234
+ - ⣧
235
+ - ⣨
236
+ - ⣩
237
+ - ⣪
238
+ - ⣫
239
+ - ⣬
240
+ - ⣭
241
+ - ⣮
242
+ - ⣯
243
+ - ⣰
244
+ - ⣱
245
+ - ⣲
246
+ - ⣳
247
+ - ⣴
248
+ - ⣵
249
+ - ⣶
250
+ - ⣷
251
+ - ⣸
252
+ - ⣹
253
+ - ⣺
254
+ - ⣻
255
+ - ⣼
256
+ - ⣽
257
+ - ⣾
258
+ - ⣿
259
+