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 +4 -4
- data/.travis.yml +1 -0
- data/Gemfile.lock +10 -10
- data/lib/unpwn/version.rb +1 -1
- data/lib/unpwn.rb +39 -6
- data/lib/unpwned_validator.rb +35 -0
- data/unpwn.gemspec +2 -2
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a04f3b1e7997fc330c4ff2069c3e399fd05518ea0d85243518d6477acef7f5a8
|
4
|
+
data.tar.gz: 10b25465bd63f35460c6956c53cb918e78a3002523a37af88bcedf888e4960cd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 669ab5c727080d5f32d72e5e8a582b6756071965abdb0104a45292a886eb26761f5c5190c6b390136bdfaa049b65084d197c0a3655bed90cec9c388d888bca67
|
7
|
+
data.tar.gz: d411bb396f905ade6953c851a1a0a3a6419814696332e2abbc583378a96ef79954f509e8e2882d861bc137b3a30ccc22c209feafb09baafe7dfee7d5d6096cde
|
data/.travis.yml
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
unpwn (0.
|
4
|
+
unpwn (1.0.0)
|
5
5
|
bloomer (~> 1.0)
|
6
|
-
pwned (~>
|
6
|
+
pwned (~> 2.0)
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
|
-
addressable (2.
|
12
|
-
public_suffix (>= 2.0.2, <
|
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.
|
30
|
-
public_suffix (
|
31
|
-
pwned (
|
32
|
-
rake (
|
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 (~>
|
56
|
+
rake (~> 12.3)
|
57
57
|
rspec (~> 3.0)
|
58
58
|
unpwn!
|
59
59
|
|
60
60
|
BUNDLED WITH
|
61
|
-
2.
|
61
|
+
2.2.21
|
data/lib/unpwn/version.rb
CHANGED
data/lib/unpwn.rb
CHANGED
@@ -1,13 +1,26 @@
|
|
1
1
|
require "unpwn/version"
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
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)
|
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", "~>
|
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", "~>
|
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.
|
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:
|
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: '
|
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: '
|
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: '
|
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: '
|
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:
|