unpwn 0.3.0 → 1.0.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: 50c1081ffc7e72b8a1e361ad624adf96198a4c6e514591b3594882a2a9def135
4
- data.tar.gz: 65d5f0f41746f64b9cc91861e664c85fd7d9d0f15242459b4a928e9e47bdab18
3
+ metadata.gz: a04f3b1e7997fc330c4ff2069c3e399fd05518ea0d85243518d6477acef7f5a8
4
+ data.tar.gz: 10b25465bd63f35460c6956c53cb918e78a3002523a37af88bcedf888e4960cd
5
5
  SHA512:
6
- metadata.gz: 55b0fead2d885c1ea121c6f188225dfd6ba75a8ddb921c43d188f74d33b2bcc466d2dda1a9fffd7905cd5353ba4b1b5f17a702810a63a04b83f9d819aa37efc1
7
- data.tar.gz: e1479fe39d6fd86d6a450ceb35681c4311d7125ebeb2c9da382301a0d7d13b4bcf8256f5205fcbf969295ff5459c57ac04c741c3b5160f87242249e0dc2d8891
6
+ metadata.gz: 669ab5c727080d5f32d72e5e8a582b6756071965abdb0104a45292a886eb26761f5c5190c6b390136bdfaa049b65084d197c0a3655bed90cec9c388d888bca67
7
+ data.tar.gz: d411bb396f905ade6953c851a1a0a3a6419814696332e2abbc583378a96ef79954f509e8e2882d861bc137b3a30ccc22c209feafb09baafe7dfee7d5d6096cde
data/.travis.yml CHANGED
@@ -4,4 +4,5 @@ language: ruby
4
4
  cache: bundler
5
5
  rvm:
6
6
  - 2.6.0
7
+ - 2.7.1
7
8
  before_install: "gem install 'bundler:~>2.0'"
data/Gemfile.lock CHANGED
@@ -1,15 +1,15 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- unpwn (0.3.0)
4
+ unpwn (1.0.0)
5
5
  bloomer (~> 1.0)
6
- pwned (~> 1.2)
6
+ pwned (~> 2.0)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- addressable (2.5.2)
12
- public_suffix (>= 2.0.2, < 4.0)
11
+ addressable (2.8.0)
12
+ public_suffix (>= 2.0.2, < 5.0)
13
13
  bitarray (1.2.0)
14
14
  bloomer (1.0.0)
15
15
  bitarray
@@ -26,10 +26,10 @@ GEM
26
26
  domain_name (~> 0.5)
27
27
  http-form_data (2.1.1)
28
28
  http_parser.rb (0.6.0)
29
- msgpack (1.3.1)
30
- public_suffix (3.0.3)
31
- pwned (1.2.1)
32
- rake (10.5.0)
29
+ msgpack (1.4.2)
30
+ public_suffix (4.0.6)
31
+ pwned (2.3.0)
32
+ rake (12.3.3)
33
33
  rspec (3.8.0)
34
34
  rspec-core (~> 3.8.0)
35
35
  rspec-expectations (~> 3.8.0)
@@ -53,9 +53,9 @@ PLATFORMS
53
53
  DEPENDENCIES
54
54
  bundler (>= 1)
55
55
  http (~> 4.0)
56
- rake (~> 10.0)
56
+ rake (~> 12.3)
57
57
  rspec (~> 3.0)
58
58
  unpwn!
59
59
 
60
60
  BUNDLED WITH
61
- 2.0.1
61
+ 2.2.21
data/lib/unpwn/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  class Unpwn
2
- VERSION = "0.3.0"
2
+ VERSION = "1.0.0"
3
3
  end
data/lib/unpwn.rb CHANGED
@@ -1,13 +1,26 @@
1
1
  require "unpwn/version"
2
2
 
3
- require "bloomer"
4
- require "bloomer/msgpackable"
5
- require "pwned"
6
-
7
- # Unpwn.pwned? tells you if a password should be rejected.
3
+ # Unpwn checks passwords locally against the top one million passwords, as
4
+ # provided by the nbp project. Then, it uses the haveibeenpwned API to check
5
+ # proposed passwords against the largest corpus of publicly dumped passwords in
6
+ # the world.
8
7
  class Unpwn
8
+ class << self
9
+ # Set `offline` to true to disable requests to the haveibeenpwned.com API
10
+ attr_accessor :offline
11
+
12
+ # Check if a password is _not_ already published. To set options like
13
+ # `min`, `max`, or on the Pwned API check, create a new instance of your
14
+ # own.
15
+ def acceptable?(password)
16
+ new.acceptable?(password)
17
+ end
18
+ end
19
+
9
20
  attr_reader :min, :max, :request_options
10
21
 
22
+ # Set the options for an Unpwn instance. `request_options` will be passed
23
+ # verbatim to the `Pwned` library.
11
24
  def initialize(min: 8, max: nil, request_options: nil)
12
25
  raise ArgumentError if min && min < 8
13
26
  raise ArgumentError if max && max < 64
@@ -17,6 +30,7 @@ class Unpwn
17
30
  @request_options = request_options || {}
18
31
  end
19
32
 
33
+ # Check if a password meets the requirements and is not pwned.
20
34
  def acceptable?(password)
21
35
  return false if min && password.size < min
22
36
  return false if max && password.size > max
@@ -24,15 +38,34 @@ class Unpwn
24
38
  !pwned?(password)
25
39
  end
26
40
 
41
+ # Checks if a password is pwned, via bloom filter then `Pwned`.
27
42
  def pwned?(password)
28
- bloom.include?(password) || Pwned.pwned?(password, request_options)
43
+ pwned = bloom.include?(password)
44
+
45
+ unless self.class.offline
46
+ require "pwned"
47
+ pwned ||= Pwned.pwned?(password, request_options)
48
+ end
49
+
50
+ pwned
29
51
  end
30
52
 
31
53
  def bloom
32
54
  @bloom ||= begin
55
+ require "bloomer"
56
+ require "bloomer/msgpackable"
33
57
  top = File.read File.expand_path("top1000000.msgpack", __dir__)
34
58
  Bloomer.from_msgpack(top)
35
59
  end
36
60
  end
37
61
 
62
+ def inspect
63
+ "<UnPwn bloomed=#{@bloom ? 'yes' : 'no'}>"
64
+ end
65
+
66
+ alias :to_s :inspect
67
+ end
68
+
69
+ if defined?(ActiveModel) || defined?(Rails)
70
+ autoload :UnpwnedValidator, "unpwned_validator"
38
71
  end
@@ -0,0 +1,35 @@
1
+ require "unpwn"
2
+
3
+ # Validator class for passwords
4
+ #
5
+ # ==== Examples
6
+ #
7
+ # Validates that attribute is not pwned, but only in production.
8
+ #
9
+ # class User < ActiveRecord::Base
10
+ # validates :password, unpwned: true, if: -> { Rails.env.production? }
11
+ # end
12
+ #
13
+ # Validates that attribute meets min/max and is not pwned.
14
+ #
15
+ # class User < ActiveRecord::Base
16
+ # validates :password, unpwned: { min: 12, max: 128 }
17
+ # end
18
+ class UnpwnedValidator < ActiveModel::EachValidator
19
+ def validate_each(record, attribute, value)
20
+ unpwn = Unpwn.new(**options.slice(:min, :max, :request_options))
21
+
22
+ if unpwn.min && value.length < unpwn.min
23
+ record.errors.add attribute, "is too short"
24
+ end
25
+
26
+ if unpwn.max && value.length > unpwn.max
27
+ record.errors.add attribute, "is too long"
28
+ end
29
+
30
+ if unpwn.pwned?(value)
31
+ record.errors.add attribute, options.fetch(:message,
32
+ "is in common password lists, please choose something more unique")
33
+ end
34
+ end
35
+ end
data/unpwn.gemspec CHANGED
@@ -21,10 +21,10 @@ Gem::Specification.new do |spec|
21
21
  spec.require_paths = ["lib"]
22
22
 
23
23
  spec.add_dependency "bloomer", "~> 1.0"
24
- spec.add_dependency "pwned", "~> 1.2"
24
+ spec.add_dependency "pwned", "~> 2.0"
25
25
 
26
26
  spec.add_development_dependency "bundler", ">= 1"
27
27
  spec.add_development_dependency "http", "~> 4.0"
28
- spec.add_development_dependency "rake", "~> 10.0"
28
+ spec.add_development_dependency "rake", "~> 12.3"
29
29
  spec.add_development_dependency "rspec", "~> 3.0"
30
30
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unpwn
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andre Arko
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-09-16 00:00:00.000000000 Z
11
+ date: 2021-09-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bloomer
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.2'
33
+ version: '2.0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.2'
40
+ version: '2.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -72,14 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '10.0'
75
+ version: '12.3'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '10.0'
82
+ version: '12.3'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rspec
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -115,6 +115,7 @@ files:
115
115
  - lib/top1000000.msgpack
116
116
  - lib/unpwn.rb
117
117
  - lib/unpwn/version.rb
118
+ - lib/unpwned_validator.rb
118
119
  - unpwn.gemspec
119
120
  homepage: https://github.com/indirect/unpwn
120
121
  licenses: