toolrack 0.9.0 → 0.10.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.
- checksums.yaml +4 -4
- data/README.md +54 -4
- data/lib/toolrack/password_utils.rb +282 -3
- data/lib/toolrack/version.rb +1 -1
- data/lib/toolrack.rb +13 -1
- data/toolrack.gemspec +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6e976dbea0f65aaafda38f95d4ae09824a98b3286f92b36b56e8caa2bd1bc342
|
4
|
+
data.tar.gz: 985e060c28df014cdfdf507a78f5601f24918b10e405bd0879e1f6d00355cb3e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 196a38ae3b58129c33713d02579ee2301888a7bec935fd5882c6ad775bdc090fcd80e563f6c072a1913c45127d5ec642fa1cfac99238ad9e44a4d29e59786fc9
|
7
|
+
data.tar.gz: c4d1173f3824c72652096e94834f829cf36740885df519cbf0e4f30393ea19e7dee2895221e31a7ba26a2a6e1de10d27fb5042f147c636b0d9dc4f58ce39e8f0
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Toolrack
|
2
2
|
|
3
|
-
Toolrack just the collection of utilities that helps in my code clarity
|
3
|
+
Toolrack just the collection of utilities that helps in my code clarity and assistance since those utils too small to be a gem on its own.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -40,10 +40,21 @@ class EditController
|
|
40
40
|
# enable instance method to access those uitilities
|
41
41
|
include ToolRack::ConditionUtils
|
42
42
|
include ToolRack::ExceptionUtils
|
43
|
+
include ToolRack::PasswordUtils
|
44
|
+
include ToolRack::RuntimeUtils
|
45
|
+
include ToolRack::DataConversionUtils
|
46
|
+
|
47
|
+
# there is also shortcut since I write it so often
|
48
|
+
include TR::CondUtils
|
49
|
+
include TR::ExpUtils
|
50
|
+
include TR::PassUtils
|
51
|
+
include TR::RTUtils
|
52
|
+
include TR::DataConvUtils
|
43
53
|
end
|
44
54
|
```
|
45
55
|
|
46
|
-
Currently it has
|
56
|
+
Currently it has 5 modules:
|
57
|
+
|
47
58
|
* Condition Utilities
|
48
59
|
* is\_empty?(obj) - I found that I've type the condition if not (x.nil? and x.empty?) too frequent that I think this is very best to turn this into a function. The empty test shall take the following test in sequence:
|
49
60
|
* First test is x.nil?. If it is return true
|
@@ -77,6 +88,45 @@ Currently it has 3 modules:
|
|
77
88
|
* raise\_if\_false(obj, message, error) - As the name implied
|
78
89
|
* raise\_if\_true(obj, message, error) - As the name implied
|
79
90
|
|
80
|
-
|
81
|
-
|
91
|
+
* Runtime utils - Tired rewriting this in other project. Detect if the running system is on which operating system / runtime. The function is pretty self descriptive
|
92
|
+
* RuntimeUtils.on\_windows?
|
93
|
+
* RuntimeUtils.on\_mac?
|
94
|
+
* RuntimeUtils.on\_linux?
|
95
|
+
* RuntimeUtils.on\_ruby?
|
96
|
+
* RuntimeUtils.on\_jruby?
|
97
|
+
|
98
|
+
* Password utils - Generate random password with designated complexity
|
99
|
+
* generate\_random\_password(length, options = { complexity: \<value\>, enforce\_quality: \<true/false\> })
|
100
|
+
* length - length of the required generated password
|
101
|
+
* options[:complexity]:
|
102
|
+
* 1 - lowercase alphabet
|
103
|
+
* 2 - lower + upper case alphabet [alpha]
|
104
|
+
* 3 - lower + upper + number [alpha numeric]
|
105
|
+
* 4 - lower + upper + number + symbol
|
106
|
+
* options[:enforce\_quality]
|
107
|
+
* true - generated password is guaranteed to contain the required complexity. E.g. if complexity 4 is required, the password MUST contain lower, upper, number and symbol as its output or a new password that comply to the complexity shall be regenerated. This process is repeated until the required complexity is achieved
|
108
|
+
* false - The rules of the complexity is relexed. E.g. if complexity 4 is requested, the output might not have symbol in it.
|
109
|
+
* gen\_rand\_pass(length, options = { }) & gen\_pass(length, options = { })
|
110
|
+
* Alias for method generate\_random\_password
|
111
|
+
|
112
|
+
* all\_lowercase\_alpha?(str)
|
113
|
+
* all\_uppercase\_alpha?(str)
|
114
|
+
* all\_alpha?(str)
|
115
|
+
* all\_number?(str)
|
116
|
+
* all\_symbol?(str)
|
117
|
+
* all\_alpha\_numeric?(str)
|
118
|
+
* all\_alpha\_numeric\_and\_symbol?(str)
|
119
|
+
* All methods above starts with all_\* is to check for strict compliance to the required output. E.g. if all\_alpha?(str) is used, the input str MUST be all alpha to get a true status
|
120
|
+
|
121
|
+
* has\_lowercase\_alpha?(str)
|
122
|
+
* has\_uppercase\_alpha?(str)
|
123
|
+
* has\_alpha?(str)
|
124
|
+
* has\_number?(str)
|
125
|
+
* has\_symbol?(str)
|
126
|
+
* has\_alpha\_numeric?(str)
|
127
|
+
* has\_alpha\_numeric\_or\_symbol?(str)
|
128
|
+
* All methods above start with has_\* is just to check if the given str contains the required specification. E.g string 'abcdE' will still get true status if pass to has\_lowercase\_alpha?(str). But value 1234 or '1234' or '$%^&' pass to has\_lowercase\_alpha?(str) shall return false.
|
129
|
+
|
130
|
+
|
131
|
+
Check out the rspec folder for usage
|
82
132
|
|
@@ -5,18 +5,297 @@ module Antrapol
|
|
5
5
|
module ToolRack
|
6
6
|
module PasswordUtils
|
7
7
|
include Antrapol::ToolRack::ConditionUtils
|
8
|
+
|
9
|
+
class PasswordUtilsError < StandardError; end
|
10
|
+
|
11
|
+
# complexity
|
12
|
+
# 1 : lowercase alphabet
|
13
|
+
# 2 : lower + upper alphabet
|
14
|
+
# 3 : lower + upper + number
|
15
|
+
# 4 : lower + upper + number + symbol
|
16
|
+
def generate_random_password(length = 12, opts = { complexity: 4, enforce_quality: true })
|
17
|
+
|
8
18
|
|
9
|
-
def generate_random_password(length = 12)
|
10
19
|
length = 12 if is_empty?(length)
|
11
20
|
length = length.to_i
|
12
21
|
length = 12 if length <= 0
|
13
22
|
|
14
|
-
|
15
|
-
|
23
|
+
logger.debug "Length : #{length}"
|
24
|
+
|
25
|
+
if not_empty?(opts)
|
26
|
+
complexity = opts[:complexity] || 4
|
27
|
+
|
28
|
+
raise PasswordUtilsError, "Password length too short but complexity too high. Not able generate the password with required complexity." if length <= complexity
|
29
|
+
|
30
|
+
enforce_quality = opts[:enforce_quality] || true
|
31
|
+
end
|
32
|
+
|
33
|
+
complexity = 4 if is_empty?(complexity)
|
34
|
+
complexity = 4 if complexity > 4
|
35
|
+
complexity = 1 if complexity < 1
|
36
|
+
|
37
|
+
logger.debug "Complexity : #{complexity}"
|
38
|
+
|
39
|
+
enforce_quality = true if is_empty?(enforce_quality) or not is_bool?(enforce_quality)
|
40
|
+
|
41
|
+
res = []
|
42
|
+
antropy = [("a".."z"),("A".."Z"),(0..9),("!".."?")]
|
43
|
+
selection = antropy[0..complexity-1].map { |s| s.to_a }.flatten
|
44
|
+
|
45
|
+
fres = nil
|
46
|
+
loop do
|
47
|
+
|
48
|
+
len = length
|
49
|
+
processed = 0
|
50
|
+
loop do
|
51
|
+
#res += selection.sample(length)
|
52
|
+
res += selection.sort_by { SecureRandom.random_number }
|
53
|
+
break if res.length >= length
|
54
|
+
end
|
55
|
+
|
56
|
+
fres = res[0...length].join
|
57
|
+
|
58
|
+
if enforce_quality
|
59
|
+
case complexity
|
60
|
+
when 1
|
61
|
+
if all_lowercase_alpha?(fres)
|
62
|
+
break
|
63
|
+
else
|
64
|
+
logger.debug "Failed lowercase alpha quality check. #{fres} - Regenerating..."
|
65
|
+
res.clear
|
66
|
+
end
|
67
|
+
when 2
|
68
|
+
st, dst = all_alpha?(fres)
|
69
|
+
if st
|
70
|
+
break
|
71
|
+
else
|
72
|
+
logger.debug "Failed all alpha quality check. #{dst} - Regenerating..."
|
73
|
+
res.clear
|
74
|
+
end
|
75
|
+
when 3
|
76
|
+
st, dst = all_alpha_numeric?(fres)
|
77
|
+
if st
|
78
|
+
break
|
79
|
+
else
|
80
|
+
logger.debug "Failed alpha numeric quality check. #{dst} - Regenerating"
|
81
|
+
res.clear
|
82
|
+
end
|
83
|
+
when 4
|
84
|
+
st, dst = all_alpha_numeric_and_symbol?(fres)
|
85
|
+
if st
|
86
|
+
break
|
87
|
+
else
|
88
|
+
logger.debug "Failed alpha numeric + symbol quality check. #{fres} / #{dst} - Regenerating"
|
89
|
+
res.clear
|
90
|
+
end
|
91
|
+
else
|
92
|
+
logger.debug "Unknown complexity?? #{complexity}"
|
93
|
+
break
|
94
|
+
end
|
95
|
+
else
|
96
|
+
break
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
fres
|
102
|
+
|
103
|
+
#length = 12 if is_empty?(length)
|
104
|
+
#length = length.to_i
|
105
|
+
#length = 12 if length <= 0
|
106
|
+
|
107
|
+
#antropy = ('!'..'~').to_a
|
108
|
+
#antropy.sort_by { SecureRandom.random_number }.join[0...length]
|
16
109
|
end
|
17
110
|
alias_method :gen_rand_pass, :generate_random_password
|
18
111
|
alias_method :gen_pass, :generate_random_password
|
19
112
|
|
113
|
+
def all_lowercase_alpha?(str)
|
114
|
+
return false if is_empty?(str) or not str.is_a?(String)
|
115
|
+
|
116
|
+
s = str.split("")
|
117
|
+
lalpha = ('a'..'z').to_a
|
118
|
+
|
119
|
+
(s.difference(lalpha).length == 0)
|
120
|
+
end
|
121
|
+
|
122
|
+
def has_lowercase_alpha?(str)
|
123
|
+
return false if is_empty?(str) or not str.is_a?(String)
|
124
|
+
|
125
|
+
s = str.split("")
|
126
|
+
lalpha = ('a'..'z').to_a
|
127
|
+
|
128
|
+
(s & lalpha).length > 0
|
129
|
+
end
|
130
|
+
|
131
|
+
def all_uppercase_alpha?(str)
|
132
|
+
return false if is_empty?(str) or not str.is_a?(String)
|
133
|
+
|
134
|
+
s = str.split("")
|
135
|
+
ualpha = ('A'..'Z').to_a
|
136
|
+
|
137
|
+
s.difference(ualpha).length == 0
|
138
|
+
end
|
139
|
+
|
140
|
+
def has_uppercase_alpha?(str)
|
141
|
+
return false if is_empty?(str) or not str.is_a?(String)
|
142
|
+
|
143
|
+
s = str.split("")
|
144
|
+
ualpha = ('A'..'Z').to_a
|
145
|
+
|
146
|
+
(s & ualpha).length > 0
|
147
|
+
end
|
148
|
+
|
149
|
+
def all_alpha?(str)
|
150
|
+
return false if is_empty?(str) or not str.is_a?(String)
|
151
|
+
|
152
|
+
s = str.split("")
|
153
|
+
lalpha = ('a'..'z').to_a
|
154
|
+
ualpha = ('A'..'Z').to_a
|
155
|
+
num = ('0'..'9').to_a
|
156
|
+
sym = ('!'..'?').to_a
|
157
|
+
|
158
|
+
alpha = [lalpha, ualpha].flatten
|
159
|
+
|
160
|
+
t1 = (alpha.difference(s).length == 0)
|
161
|
+
t2 = (alpha.difference(s).length == 0)
|
162
|
+
|
163
|
+
t3 = (s & num).length > 0
|
164
|
+
t4 = (s & sym).length > 0
|
165
|
+
|
166
|
+
[!(t1 or t2 or t3 or t4), res = { has_lower_alpha: t1, has_upper_alpha: t2, has_num: t3, has_symbol: t4 }]
|
167
|
+
end
|
168
|
+
|
169
|
+
def has_alpha?(str)
|
170
|
+
return false if is_empty?(str) or not str.is_a?(String)
|
171
|
+
|
172
|
+
s = str.split("")
|
173
|
+
lalpha = ('a'..'z').to_a
|
174
|
+
ualpha = ('A'..'Z').to_a
|
175
|
+
alpha = [lalpha, ualpha].flatten
|
176
|
+
|
177
|
+
(alpha & s).length > 0
|
178
|
+
end
|
179
|
+
|
180
|
+
def has_number?(str)
|
181
|
+
return false if is_empty?(str)
|
182
|
+
|
183
|
+
str = str.to_s if not str.is_a?(String)
|
184
|
+
|
185
|
+
s = str.split("")
|
186
|
+
num = ('0'..'9').to_a
|
187
|
+
|
188
|
+
(s & num).length > 0
|
189
|
+
|
190
|
+
end
|
191
|
+
|
192
|
+
def all_number?(str)
|
193
|
+
return false if is_empty?(str)
|
194
|
+
|
195
|
+
str = str.to_s if not str.is_a?(String)
|
196
|
+
|
197
|
+
s = str.split("")
|
198
|
+
num = ('0'..'9').to_a
|
199
|
+
|
200
|
+
!(s.difference(num).length > 0)
|
201
|
+
|
202
|
+
end
|
203
|
+
|
204
|
+
def all_symbol?(str)
|
205
|
+
return false if is_empty?(str)
|
206
|
+
|
207
|
+
s = str.split("")
|
208
|
+
sym = ('!'..'?').to_a
|
209
|
+
!(s.difference(sym).length > 0)
|
210
|
+
|
211
|
+
end
|
212
|
+
|
213
|
+
def has_symbol?(str)
|
214
|
+
return false if is_empty?(str)
|
215
|
+
|
216
|
+
s = str.split("")
|
217
|
+
sym = ('!'..'?').to_a
|
218
|
+
|
219
|
+
p (s & sym)
|
220
|
+
(s & sym).length > 0
|
221
|
+
end
|
222
|
+
|
223
|
+
|
224
|
+
def all_alpha_numeric?(str)
|
225
|
+
return false if is_empty?(str)
|
226
|
+
|
227
|
+
s = str.split("")
|
228
|
+
lalpha = ('a'..'z').to_a
|
229
|
+
ualpha = ('A'..'Z').to_a
|
230
|
+
num = ('0'..'9').to_a
|
231
|
+
sym = ('!'..'?').to_a
|
232
|
+
sym = sym.difference(num)
|
233
|
+
|
234
|
+
t1 = ((s & lalpha).length > 0)
|
235
|
+
t2 = ((s & ualpha).length > 0)
|
236
|
+
t3 = ((s & num).length > 0)
|
237
|
+
|
238
|
+
t4 = ((s & sym).length > 0)
|
239
|
+
|
240
|
+
[(t1 and t2 and t3 and !t4), res = { has_lower_alpha: t1, has_upper_alpha: t2, has_num: t3, has_symbol: t4 }]
|
241
|
+
end
|
242
|
+
|
243
|
+
def has_alpha_numeric?(str)
|
244
|
+
return false if is_empty?(str)
|
245
|
+
|
246
|
+
s = str.split("")
|
247
|
+
lalpha = ('a'..'z').to_a
|
248
|
+
ualpha = ('A'..'Z').to_a
|
249
|
+
num = ('0'..'9').to_a
|
250
|
+
alphanum = [lalpha, ualpha, num].flatten
|
251
|
+
|
252
|
+
(s & alphanum).length > 0
|
253
|
+
|
254
|
+
end
|
255
|
+
|
256
|
+
def all_alpha_numeric_and_symbol?(str)
|
257
|
+
return false if is_empty?(str)
|
258
|
+
|
259
|
+
s = str.split("")
|
260
|
+
lalpha = ('a'..'z').to_a
|
261
|
+
ualpha = ('A'..'Z').to_a
|
262
|
+
num = ('0'..'9').to_a
|
263
|
+
sym = ('!'..'?').to_a
|
264
|
+
sym = sym.difference(num)
|
265
|
+
|
266
|
+
t1 = ((s & lalpha).length > 0)
|
267
|
+
t2 = ((s & ualpha).length > 0)
|
268
|
+
t3 = ((s & num).length > 0)
|
269
|
+
t4 = ((s & sym).length > 0)
|
270
|
+
|
271
|
+
[(t1 and t2 and t3 and t4), res = { has_lower_alpha: t1, has_upper_alpha: t2, has_num: t3, has_symbol: t4 }]
|
272
|
+
end
|
273
|
+
|
274
|
+
def has_alpha_numeric_or_symbol?(str)
|
275
|
+
return false if is_empty?(str)
|
276
|
+
|
277
|
+
s = str.split("")
|
278
|
+
lalpha = ('a'..'z').to_a
|
279
|
+
ualpha = ('A'..'Z').to_a
|
280
|
+
num = ('0'..'9').to_a
|
281
|
+
sym = ('!'..'?').to_a
|
282
|
+
sym = sym.difference(num)
|
283
|
+
|
284
|
+
t1 = ((s & lalpha).length > 0)
|
285
|
+
t2 = ((s & ualpha).length > 0)
|
286
|
+
t3 = ((s & num).length > 0)
|
287
|
+
t4 = ((s & sym).length > 0)
|
288
|
+
|
289
|
+
[(t1 or t2 or t3 or t4), res = { has_lower_alpha: t1, has_upper_alpha: t2, has_num: t3, has_symbol: t4 }]
|
290
|
+
end
|
291
|
+
|
292
|
+
private
|
293
|
+
def logger
|
294
|
+
logger = Antrapol::ToolRack::Logger.instance.glogger
|
295
|
+
logger.tag = :pass_utils
|
296
|
+
logger
|
297
|
+
end
|
298
|
+
|
20
299
|
end
|
21
300
|
end
|
22
301
|
end
|
data/lib/toolrack/version.rb
CHANGED
data/lib/toolrack.rb
CHANGED
@@ -22,8 +22,20 @@ module Antrapol
|
|
22
22
|
end
|
23
23
|
|
24
24
|
ToolRack = Antrapol::ToolRack
|
25
|
-
|
25
|
+
TR = ToolRack
|
26
|
+
|
27
|
+
ToolRack::DataConvUtils = Antrapol::ToolRack::DataConversionUtils
|
28
|
+
TR::DataConvUtils = ToolRack::DataConvUtils
|
29
|
+
|
26
30
|
ToolRack::CondUtils = ToolRack::ConditionUtils
|
31
|
+
TR::CondUtils = ToolRack::ConditionUtils
|
32
|
+
|
27
33
|
ToolRack::PassUtils = ToolRack::PasswordUtils
|
34
|
+
TR::PassUtils = ToolRack::PasswordUtils
|
35
|
+
|
36
|
+
ToolRack::ExpUtils = ToolRack::ExceptionUtils
|
37
|
+
TR::ExpUtils = ToolRack::ExpUtils
|
28
38
|
|
39
|
+
ToolRack::RTUtils = ToolRack::RuntimeUtils
|
40
|
+
TR::RTUtils = ToolRack::RTUtils
|
29
41
|
|
data/toolrack.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.summary = %q{Collection of simple utilities but I find it increase clarity}
|
10
10
|
spec.description = %q{Just collections of utilities}
|
11
11
|
spec.homepage = "https://github.com/chrisliaw/toolrack"
|
12
|
-
spec.required_ruby_version = Gem::Requirement.new(">= 2.
|
12
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.6.0")
|
13
13
|
|
14
14
|
#spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
|
15
15
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: toolrack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-09-
|
11
|
+
date: 2021-09-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: tlogger
|
@@ -88,7 +88,7 @@ licenses: []
|
|
88
88
|
metadata:
|
89
89
|
homepage_uri: https://github.com/chrisliaw/toolrack
|
90
90
|
source_code_uri: https://github.com/chrisliaw/toolrack
|
91
|
-
post_install_message:
|
91
|
+
post_install_message:
|
92
92
|
rdoc_options: []
|
93
93
|
require_paths:
|
94
94
|
- lib
|
@@ -96,7 +96,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
96
96
|
requirements:
|
97
97
|
- - ">="
|
98
98
|
- !ruby/object:Gem::Version
|
99
|
-
version: 2.
|
99
|
+
version: 2.6.0
|
100
100
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
101
|
requirements:
|
102
102
|
- - ">="
|
@@ -104,7 +104,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
104
104
|
version: '0'
|
105
105
|
requirements: []
|
106
106
|
rubygems_version: 3.2.22
|
107
|
-
signing_key:
|
107
|
+
signing_key:
|
108
108
|
specification_version: 4
|
109
109
|
summary: Collection of simple utilities but I find it increase clarity
|
110
110
|
test_files: []
|