rack-u2f 0.1.2 → 0.1.3

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
  SHA1:
3
- metadata.gz: 39c69e83247c51be9d502293e7e83157b0995713
4
- data.tar.gz: 146f77e789e30cdeecae8662ef149298e9a7c568
3
+ metadata.gz: fadfe6cc870a2dbed3a6fcde4be9f7cb309ca2d0
4
+ data.tar.gz: 562f528d75d8eeccc0901eed6367cb9bac0723e5
5
5
  SHA512:
6
- metadata.gz: b197fa625b8852b8f735bcf5df26344011e1ff7412962dbbbc39c5a9daa832c7624d665e6b2f70e4451e11b97e9eaa57858be78f2332f26c787df41488009038
7
- data.tar.gz: 22fd071a1fd8971aeb34dcf4e0736a2ec91714aadb2ecc7b048b365249a3958a9167ef422c9a64ac3e4329c2a1253e2e776a26bb52839fe05b4f396d0cf8f6e0
6
+ metadata.gz: 712654a48a465300d0af1a9f81456077e8f78f6f0b207c4691a37d27b09350490b353b517b7081f9ca8bd75bac5b0d9514910d25741adab6d24c6730573f8e8b
7
+ data.tar.gz: 2dabffb61eb6ba305a610166f47a432364f5d60ddbd1215c656a2f3a8f57905967df08ca23145d513992a7b1c448be73b7a00f66f93f9b1113d1c41ce3b48bbe
data/README.md CHANGED
@@ -25,7 +25,7 @@ And then execute:
25
25
 
26
26
  Rack U2F has two components; A Rack app to register U2F devices and Rack Middleware to authenticate against registered U2F devices. When registration is enabled, you can add a u2f device through the `u2f_register_path`.
27
27
 
28
- For U2F to work, persistence of a counter is required, therefore a storage mechanism is needed. Right now, this gem supports [Redis](https://redis.io), but ActiveRecord support is also planned.
28
+ For U2F to work, persistence of a counter is required, therefore a storage mechanism is needed. Right now, this gem supports [Redis](https://redis.io), and ActiveRecord. There is a simple API to add more stores as required.
29
29
 
30
30
  ## Config
31
31
 
@@ -43,6 +43,10 @@ config.middleware.use Rack::U2f::AuthenticationMiddleware, {
43
43
  }
44
44
  ```
45
45
 
46
+ ## Store Config
47
+
48
+ ### Redis Store
49
+
46
50
  The `Rack::U2f::RegistrationStore::RedisStore.new` by default uses `Redis.new` as the redis connection.
47
51
  You can pass in your own connection as the single argument to `RedisStore.new()`, for example:
48
52
 
@@ -50,11 +54,35 @@ You can pass in your own connection as the single argument to `RedisStore.new()`
50
54
  store: Rack::U2f::RegistrationStore::RedisStore.new(Redis.new(url: 'redis://10.1.1.1/'))
51
55
  ```
52
56
 
57
+ ### ActiveRecord Store
58
+
59
+ Use `Rack::U2f::RegistrationStore::ActiveRecordStore.new(ArModel)`. The `ArModel` should be an active record model with the following schema;
60
+
61
+ ```
62
+ t.string :key_handle, index: true
63
+ t.text :certificate
64
+ t.text :public_key
65
+ t.integer :counter
66
+ ```
67
+
68
+ ## Other Config
69
+
70
+ ### enable_registration
71
+
53
72
  If `enable_registration` is true then you will be able to visit `/_u2f_register` to register a new key.
54
73
  Registration should not be enabled in production. It is possible to mount the registration server separately as it is a rack app.
55
74
 
56
75
  When authenticated, the session is for further authentication. *You must be using a secure session store*.
57
76
 
77
+ ### after_sign_in_url
78
+
79
+ The url to be directed to after successful sign in, default: `"/"`
80
+
81
+ ### exclude_urls
82
+
83
+ An array of regular expressions to match on the path to exclude urls from the u2f requirement.
84
+ Be careful here; generally prefixes is the safest way `%r{\A/myprefix}`. Keep in mind that people can add things to paths that may cause an otherwise excluded url to match.
85
+
58
86
  ## Development
59
87
 
60
88
  There is a demo app in the DemoApp folder. Integration tests will require a fake/software u2f key, and is on the TODO list.
@@ -70,3 +98,6 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/eadz/r
70
98
  ## License
71
99
 
72
100
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
101
+
102
+ ## Todo ( contributions welcome )
103
+ Integration tests using a fake token such as the [soft token helper from google]( https://github.com/google/u2f-ref-code/blob/master/u2f-chrome-extension/softtokenhelper.js)
@@ -10,37 +10,41 @@ module Rack
10
10
  def initialize(config)
11
11
  @config = config
12
12
  @store = config[:store]
13
+ @registration_enabled = config[:enable_registration]
13
14
  raise 'Missing RegistrationMiddleware Config' if @config.nil?
14
15
  end
15
16
 
16
17
  def call(env)
17
- return [403, {}, ['Registration Disabled']] unless @config[:enable_registration]
18
+ return registration_disabled unless @registration_enabled
18
19
  request = Rack::Request.new(env)
19
20
  if request.get?
20
21
  generate_registration(request)
21
22
  else
22
- u2f = U2F::U2F.new(extract_app_id(request))
23
-
24
- response = U2F::RegisterResponse.load_from_json(request.params['response'])
25
- reg = begin
26
- u2f.register!(request.session['challenges'], response)
27
- rescue U2F::Error => e
28
- return [422, {}, ['Unable to register device']]
29
- ensure
30
- request.session.delete('challenges')
31
- end
32
- @store.store_registration(
33
- certificate: reg.certificate,
34
- key_handle: reg.key_handle,
35
- public_key: reg.public_key,
36
- counter: reg.counter
37
- )
38
- return [200, {}, ["Registration Successful"]]
23
+ store_registration(request)
39
24
  end
40
25
  end
41
26
 
42
27
  private
43
28
 
29
+ def registration_disabled
30
+ Rack::Response.new('Registration Disabled', 403)
31
+ end
32
+
33
+ def store_registration(request)
34
+ u2f = U2F::U2F.new(extract_app_id(request))
35
+ response = U2F::RegisterResponse.load_from_json(request.params['response'])
36
+ u2f.register!(request.session['challenges'], response)
37
+ @store.store_registration(
38
+ certificate: reg.certificate, key_handle: reg.key_handle,
39
+ public_key: reg.public_key, counter: reg.counter
40
+ )
41
+ Rack::Response.new('Registration Successful')
42
+ rescue U2F::Error
43
+ return Rack::Response.new('Unable to register device', 422)
44
+ ensure
45
+ request.session.delete('challenges')
46
+ end
47
+
44
48
  def generate_registration(request)
45
49
  u2f = U2F::U2F.new('https://junk.ngrok.io')
46
50
  registration_requests = u2f.registration_requests
@@ -1,22 +1,23 @@
1
+ require 'rack/u2f/registration_store/active_record_store'
1
2
  require 'rack/u2f/registration_store/redis_store'
2
3
 
3
4
  module Rack
4
5
  module U2f
5
6
  # Store to keep track of tokens
6
7
  module RegistrationStore
7
- class AbstractStore
8
- def initialize(*args)
9
- end
10
-
11
- def store_registration(certificate:, key_handle:, public_key:, counter:)
12
- end
13
-
14
- def update_registration(key_handle:, counter:)
15
- end
16
-
17
- def key_handles
18
- end
19
- end
8
+ # class AbstractStore
9
+ # def initialize(*args)
10
+ # end
11
+ #
12
+ # def store_registration(certificate:, key_handle:, public_key:, counter:)
13
+ # end
14
+ #
15
+ # def update_registration(key_handle:, counter:)
16
+ # end
17
+ #
18
+ # def key_handles
19
+ # end
20
+ # end
20
21
  end
21
22
  end
22
23
  end
@@ -8,15 +8,25 @@ module Rack
8
8
  end
9
9
 
10
10
  def store_registration(certificate:, key_handle:, public_key:, counter:)
11
+ @model.create!(
12
+ certificate: certificate,
13
+ key_handle: key_handle,
14
+ public_key: public_key,
15
+ counter: counter
16
+ )
11
17
  end
12
18
 
13
19
  def get_registration(key_handle:)
20
+ key = @model.where(key_handle: key_handle).first
21
+ key && key.as_json.slice('certificate', 'public_key', 'counter')
14
22
  end
15
23
 
16
24
  def update_registration(key_handle:, counter:)
25
+ @model.where(key_handle: key_handle).update_all(counter: counter)
17
26
  end
18
27
 
19
28
  def key_handles
29
+ @model.pluck(:key_handle)
20
30
  end
21
31
  end
22
32
  end
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  module U2f
3
- VERSION = "0.1.2"
3
+ VERSION = '0.1.3'.freeze
4
4
  end
5
5
  end
@@ -26,9 +26,11 @@ Gem::Specification.new do |spec|
26
26
  spec.add_dependency 'rack', '~> 2.0'
27
27
  spec.add_dependency 'u2f', '~> 1.0'
28
28
 
29
+ spec.add_development_dependency 'activerecord', '>= 4.0'
29
30
  spec.add_development_dependency 'bundler', '~> 1.15'
30
31
  spec.add_development_dependency 'fakeredis', '~> 0.6.0'
31
32
  spec.add_development_dependency 'rake', '~> 10.0'
32
33
  spec.add_development_dependency 'redis', '~> 3.2'
33
34
  spec.add_development_dependency 'rspec', '~> 3.0'
35
+ spec.add_development_dependency 'sqlite3', '~> 1.3'
34
36
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-u2f
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eaden McKee
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-11-08 00:00:00.000000000 Z
11
+ date: 2017-11-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mustache
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: activerecord
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '4.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '4.0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: bundler
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -122,6 +136,20 @@ dependencies:
122
136
  - - "~>"
123
137
  - !ruby/object:Gem::Version
124
138
  version: '3.0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: sqlite3
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '1.3'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '1.3'
125
153
  description: rack middleware to add u2f authentication to a rack app. Includes registration.
126
154
  email:
127
155
  - mail@eaden.net