xkpassword 0.3.3 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8cef9e3a5c2d5e5b5c1e0fc020c5452cc124e3e2621dbaef3d2e8534a8d32fc7
4
- data.tar.gz: d3505fb27f342fd47d4eabe8908be4512548d73c1415370cdf161027cf1ffca3
3
+ metadata.gz: 9feced30408ade895b492ff621703dd5d6a1cb6f6d4aaa6fe195534a249cb519
4
+ data.tar.gz: 8f7bde17464c36aba01028a650daaa3e37d357018e5892bd9331384f25068a6a
5
5
  SHA512:
6
- metadata.gz: 2de3ac2952363281897ba7b7ff0a360ab33a5a1802d0f27df6fe3b8662a68e8ecd20265a21879e172528bee87862e0cfe10e36b05844415fe0c0f273630b8339
7
- data.tar.gz: 41ead76491703805aefc73a7a7e9d2351293e59e19d9493e83b4b9886b0aaa18e57101dd10067f1624db3b0764bcdce48bfa7746a30ca97c070e9fbb1c4bb00b
6
+ metadata.gz: 158d3daab0101987cb7062a907125d80858aa7dbfdea51c6448ade83d4e155e5af31a87e37715ebde7a1965572008d2f56e64d747e53eb21a9a51e66c948d95b
7
+ data.tar.gz: cfa02254cb10af01efe5387605d9036750c419031e40bb47cb8a2b23f97c4364ba534f66e3629b3b335dc450fb99d965f5827b654e0e5556d81a2f202eae7664
data/Gemfile CHANGED
@@ -6,4 +6,5 @@ gemspec
6
6
  group :development do
7
7
  gem 'yard'
8
8
  gem 'pry'
9
+ gem 'rubocop', require: false
9
10
  end
data/README.md CHANGED
@@ -53,7 +53,7 @@ Or install it yourself as:
53
53
  ## Usage
54
54
 
55
55
  You can use this app stand-alone in the command line or include it in any of your Ruby
56
- applications.
56
+ applications. For a fuller guide to presets and examples, see [doc/README.md](doc/README.md).
57
57
 
58
58
  ### Comamnd Line
59
59
  The commandline application accepts the same collection of configuration options as would
@@ -71,10 +71,7 @@ full list of options.
71
71
  require 'xkpassword'
72
72
 
73
73
  options = {
74
- max_length: 8,
75
- min_length: 4,
76
- separator: '-',
77
- words: 4,
74
+ preset: :security,
78
75
  }
79
76
 
80
77
  XKPassword.generate(options)
@@ -87,10 +84,7 @@ the following as then it will only load and parse the databse once.
87
84
  require 'xkpassword/generator'
88
85
 
89
86
  options = {
90
- max_length: 8,
91
- min_length: 4,
92
- separator: '-',
93
- words: 4,
87
+ preset: :wifi,
94
88
  }
95
89
 
96
90
  generator = XKPassword::Generator.new
@@ -99,15 +93,18 @@ generator.generate(options)
99
93
  # 10.times { generator.generate(options) }
100
94
  ```
101
95
 
102
- ## The GEM
96
+ `preset` supports `:xkcd` (default), `:web32`, `:wifi`, `:security`, and `:apple_id`.
97
+ You can still override any individual option in the selected preset.
98
+
99
+ The default `:xkcd` preset keeps the gem's original behavior of generating 4 words.
103
100
 
104
- I run a policy of tagging any improvement done for the code base. For example, I just
105
- bumped a minor (resulting 0.2.3 ~> 0.3.0) for adding Travis CI which doesn't change any
106
- functional aspect of the app.
101
+ `case_transform` supports `:upcase`, `:downcase`, and `:capitalize`, and applies the
102
+ selected transform to every generated word in the password.
107
103
 
108
- I am thinking of releasing gems only on functional updates (real code changes) that
109
- happen with new features and bug fixes. So for now, there will be no 0.3.0v available
110
- in Ruby GEMs and the latest would be 0.2.3.
104
+ ## The GEM
105
+
106
+ Releases are intended for functional updates such as new features and bug fixes.
107
+ Check the Git tags or RubyGems release history for the latest published version.
111
108
 
112
109
  ## Development
113
110
 
@@ -140,4 +137,3 @@ conduct.
140
137
  ## License
141
138
 
142
139
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
143
-
data/exe/xkpassword CHANGED
@@ -39,10 +39,10 @@ OptionParser.new do |opts|
39
39
  opts.on('--min-length [INTEGER]', 'Minimum length of a word') { |min| options[:min_length] = min.to_i }
40
40
  opts.on('--max-length [INTEGER]', 'Maximum length of a word') { |max| options[:max_length] = max.to_i }
41
41
  opts.on('--separator [STRING]', 'The separator to separate password') { |separator| options[:separator] = separator }
42
+ opts.on('--case-transform [STRING]', 'Transform each word using upcase, downcase, or capitalize') { |case_transform| options[:case_transform] = case_transform }
43
+ opts.on('--preset [STRING]', 'Preset to use: xkcd, web32, wifi, security, or apple_id') { |preset| options[:preset] = preset }
42
44
  end.parse!
43
45
 
44
46
  puts message if options[:info]
45
47
  puts XKPassword::VERSION if options[:version]
46
48
  puts XKPassword.generate(options) if !options[:info] && !options[:version]
47
-
48
-
@@ -2,15 +2,60 @@ require 'xkpassword/words'
2
2
 
3
3
  # The Generator class which finds words based on the requirement and using the provided options to build a
4
4
  # new random passowrd.
5
+ # Presets provide convenient defaults for common password styles, and callers can override any
6
+ # preset-derived value by passing explicit generation options.
5
7
  #
6
8
  # @attr_reader [XKPassword::Words] words A word database that gen provide you words for the length required
7
9
  class XKPassword::Generator
8
- DEFAULTS = {
9
- max_length: 8,
10
- min_length: 4,
11
- separator: '-',
12
- words: 4,
10
+ # The preset used when `:preset` is omitted.
11
+ DEFAULT_PRESET = :xkcd
12
+
13
+ # Built-in password presets.
14
+ #
15
+ # - `:xkcd` generates 4 words between 4 and 8 letters separated by `-`, preserving the gem's
16
+ # original default behavior.
17
+ # - `:web32` generates 4 shorter words between 4 and 5 letters separated by `-`.
18
+ # - `:wifi` generates 6 words between 4 and 8 letters separated by `-`.
19
+ # - `:security` generates 6 lowercase words between 4 and 8 letters separated by spaces.
20
+ # - `:apple_id` generates 3 words between 4 and 7 letters separated by `-`.
21
+ PRESETS = {
22
+ xkcd: {
23
+ case_transform: nil,
24
+ max_length: 8,
25
+ min_length: 4,
26
+ separator: '-',
27
+ words: 4,
28
+ },
29
+ web32: {
30
+ case_transform: nil,
31
+ max_length: 5,
32
+ min_length: 4,
33
+ separator: '-',
34
+ words: 4,
35
+ },
36
+ wifi: {
37
+ case_transform: nil,
38
+ max_length: 8,
39
+ min_length: 4,
40
+ separator: '-',
41
+ words: 6,
42
+ },
43
+ security: {
44
+ case_transform: :downcase,
45
+ max_length: 8,
46
+ min_length: 4,
47
+ separator: ' ',
48
+ words: 6,
49
+ },
50
+ apple_id: {
51
+ case_transform: nil,
52
+ max_length: 7,
53
+ min_length: 4,
54
+ separator: '-',
55
+ words: 3,
56
+ },
13
57
  }
58
+ VALID_CASE_TRANSFORMS = [:upcase, :downcase, :capitalize]
14
59
 
15
60
  attr_reader :words
16
61
 
@@ -19,38 +64,96 @@ class XKPassword::Generator
19
64
  end
20
65
 
21
66
  # Generates a password absed on the configuration provided.
67
+ # A preset supplies a base configuration and any explicit options passed in `options` override
68
+ # those preset defaults.
22
69
  #
23
70
  # @param [Hash] options The options to populate a generator
71
+ # @option options [String, Symbol] :preset The preset to use. Supports `:xkcd`, `:web32`,
72
+ # `:wifi`, `:security`, and `:apple_id`.
73
+ # String values like `"apple_id"` and `"apple-id"`
74
+ # are normalized to `:apple_id`. Defaults to `:xkcd`.
24
75
  # @option options [Integer] :words The number of words to include in the generated password
25
76
  # @option options [String] :separator The separator symbol to use joining words used in password
26
77
  # @option options [Integer] :min_length The minimum length of a word to be used in the process
27
78
  # @option options [Integer] :max_length The maximum length of a word to be used in the process
79
+ # @option options [String, Symbol] :case_transform The transform to apply to every generated word
28
80
  #
29
81
  # @return [String] The generated password
30
82
  #
31
- # @example Populating the method with all options (current default)
83
+ # @example Using the default xkcd preset
84
+ # generator = XKPassword::Generator.new
85
+ # generator.generate
86
+ #
87
+ # @example Using the security preset
88
+ # generator = XKPassword::Generator.new
89
+ # generator.generate(preset: :security)
90
+ #
91
+ # @example Populating the method with a preset and explicit overrides
32
92
  # options = {
93
+ # preset: :security,
33
94
  # separator: ' ',
34
- # words: 4,
95
+ # words: 6,
35
96
  # min_length: 4,
36
- # max_length: 8
97
+ # max_length: 8,
98
+ # case_transform: :downcase
37
99
  # }
38
100
  #
39
101
  # generator = XKPassword::Generator.new
40
102
  # generator.generate(options)
103
+ #
104
+ # @example Built-in preset defaults
105
+ # :xkcd # 4 words, 4..8 letters, "-" separator, random per-word uppercasing
106
+ # :web32 # 4 words, 4..5 letters, "-" separator, random per-word uppercasing
107
+ # :wifi # 6 words, 4..8 letters, "-" separator, random per-word uppercasing
108
+ # :security # 6 words, 4..8 letters, " " separator, lowercase
109
+ # :apple_id # 3 words, 4..7 letters, "-" separator, random per-word uppercasing
41
110
  def generate(options = nil)
42
- options ||= {}
43
- options = DEFAULTS.merge(options)
111
+ options = (options || {}).dup
112
+ preset = normalize_preset(options.delete(:preset))
113
+ options = PRESETS.fetch(preset).merge(options)
114
+ case_transform = normalize_case_transform(options[:case_transform])
44
115
  length_vals = (options[:min_length]..options[:max_length]).to_a
45
116
 
46
117
  data = options[:words].times.map do
47
118
  word = words.random(length_vals.sample)
48
- upcase = [true, false].sample
49
- word = word.upcase if upcase
50
- word
119
+ transform_word(word, case_transform)
51
120
  end
52
121
 
53
122
  data.join(options[:separator])
54
123
  end
55
-
124
+
125
+ private
126
+
127
+ def transform_word(word, case_transform)
128
+ return randomly_upcase(word) unless case_transform
129
+
130
+ word.public_send(case_transform)
131
+ end
132
+
133
+ def randomly_upcase(word)
134
+ upcase = [true, false].sample
135
+ word = word.upcase if upcase
136
+ word
137
+ end
138
+
139
+ def normalize_case_transform(case_transform)
140
+ return nil if case_transform.nil?
141
+
142
+ case_transform = case_transform.to_sym if case_transform.is_a?(String)
143
+
144
+ return case_transform if VALID_CASE_TRANSFORMS.include?(case_transform)
145
+
146
+ fail ArgumentError, "case_transform should be one of: #{ VALID_CASE_TRANSFORMS.join(', ') }"
147
+ end
148
+
149
+ def normalize_preset(preset)
150
+ return DEFAULT_PRESET if preset.nil?
151
+
152
+ preset = preset.strip.downcase.tr(' -', '_').to_sym if preset.is_a?(String)
153
+
154
+ return preset if PRESETS.key?(preset)
155
+
156
+ fail ArgumentError, "preset should be one of: #{ PRESETS.keys.join(', ') }"
157
+ end
158
+
56
159
  end
@@ -1,3 +1,3 @@
1
1
  module XKPassword
2
- VERSION = '0.3.3'
2
+ VERSION = '0.5.0'
3
3
  end
data/lib/xkpassword.rb CHANGED
@@ -7,11 +7,29 @@ module XKPassword
7
7
  # use the `XKPassword::Generator` class as it will be faster since it will only need to load
8
8
  # the dictionary once.
9
9
  #
10
+ # Presets provide named defaults for common password styles, and any explicit options passed to
11
+ # this method override the selected preset.
12
+ #
10
13
  # @param [Hash] options The options to populate a generator
14
+ # @option options [String, Symbol] :preset The preset to use. Supports `:xkcd`, `:web32`,
15
+ # `:wifi`, `:security`, and `:apple_id`.
16
+ # Defaults to `:xkcd`.
17
+ # - `:xkcd` uses 4 words of 4..8 letters joined by `-`
18
+ # - `:web32` uses 4 words of 4..5 letters joined by `-`
19
+ # - `:wifi` uses 6 words of 4..8 letters joined by `-`
20
+ # - `:security` uses 6 lowercase words of 4..8 letters joined by spaces
21
+ # - `:apple_id` uses 3 words of 4..7 letters joined by `-`
11
22
  # @option options [Integer] :words The number of words to include in the generated password
12
23
  # @option options [String] :separator The separator symbol to use joining words used in password
13
24
  # @option options [Integer] :min_length The minimum length of a word to be used in the process
14
25
  # @option options [Integer] :max_length The maximum length of a word to be used in the process
26
+ # @option options [String, Symbol] :case_transform The transform to apply to every generated word
27
+ #
28
+ # @example Generate with the default preset
29
+ # XKPassword.generate
30
+ #
31
+ # @example Generate with a preset and override one of its defaults
32
+ # XKPassword.generate(preset: :apple_id, separator: '.')
15
33
  def self.generate(options = nil)
16
34
  generator = XKPassword::Generator.new
17
35
  generator.generate(options)
@@ -21,5 +39,3 @@ end
21
39
 
22
40
  require 'xkpassword/version'
23
41
  require 'xkpassword/generator'
24
-
25
-
data/mise.toml ADDED
@@ -0,0 +1,14 @@
1
+ [tools]
2
+ ruby = "3.3"
3
+
4
+ [tasks.test]
5
+ description = "Run the test suite"
6
+ run = "bundle exec rspec"
7
+
8
+ [tasks.format]
9
+ description = "Format and lint the code with RuboCop"
10
+ run = "bundle exec rubocop -a"
11
+
12
+ [tasks.publish]
13
+ description = "Build and publish the gem to RubyGems"
14
+ run = "bundle exec rake release"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xkpassword
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ziyan Junaideen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-03-25 00:00:00.000000000 Z
11
+ date: 2026-04-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: artii
@@ -81,8 +81,6 @@ extra_rdoc_files: []
81
81
  files:
82
82
  - ".gitignore"
83
83
  - ".rspec"
84
- - ".ruby-gemset"
85
- - ".ruby-version"
86
84
  - ".travis.yml"
87
85
  - CODE_OF_CONDUCT.md
88
86
  - Gemfile
@@ -99,6 +97,7 @@ files:
99
97
  - lib/xkpassword/store.rb
100
98
  - lib/xkpassword/version.rb
101
99
  - lib/xkpassword/words.rb
100
+ - mise.toml
102
101
  - xkpassword.gemspec
103
102
  homepage: https://github.com/jdeen/xkpassword
104
103
  licenses:
@@ -119,7 +118,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
119
118
  - !ruby/object:Gem::Version
120
119
  version: '0'
121
120
  requirements: []
122
- rubygems_version: 3.1.2
121
+ rubygems_version: 3.5.22
123
122
  signing_key:
124
123
  specification_version: 4
125
124
  summary: Hard to crack - XKPassword Generator for Ruby
data/.ruby-gemset DELETED
@@ -1 +0,0 @@
1
- xkpassword_gem
data/.ruby-version DELETED
@@ -1 +0,0 @@
1
- 2.3.0