rack-u2f 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
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