warden-jwt_auth 0.2.0 → 0.2.1
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/CHANGELOG.md +7 -0
- data/README.md +3 -3
- data/lib/warden/jwt_auth.rb +23 -3
- data/lib/warden/jwt_auth/env_helper.rb +52 -0
- data/lib/warden/jwt_auth/header_parser.rb +2 -4
- data/lib/warden/jwt_auth/hooks.rb +8 -6
- data/lib/warden/jwt_auth/middleware/revocation_manager.rb +10 -7
- data/lib/warden/jwt_auth/strategy.rb +3 -3
- data/lib/warden/jwt_auth/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1f24397de1422507d524eba4a8c60050e6a6abde
|
4
|
+
data.tar.gz: b767bf87c6b29a12da5a64b4367f619b8685568e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 29f2e7ef4ea4de94a68b4cac0e394df30609fa706c6afb468d725000995a68c80227abd64392367b94fda770fe7884aac11041ecd742661d96eaa8045efb04c7
|
7
|
+
data.tar.gz: ab4e91316b5ca085c1f2f1f267656097d788a2e1e5ad1cf9face21402f569aa989264c57bdb8310512d7028a0e10351697abf13ece06512c0470f9bf72b49f93
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.
|
|
4
4
|
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
5
5
|
and this project adheres to [Semantic Versioning](http://semver.org/).
|
6
6
|
|
7
|
+
## [0.2.1] - 2017-12-04
|
8
|
+
### Added
|
9
|
+
- Allow configuring classes as strings
|
10
|
+
|
11
|
+
### Fixed
|
12
|
+
- Take `PATH_INFO` as an empty string when it is not present
|
13
|
+
|
7
14
|
## [0.2.0] - 2017-11-23
|
8
15
|
### Added
|
9
16
|
- `fail!` with message
|
data/README.md
CHANGED
@@ -24,7 +24,7 @@ If what you need is a JWT authentication library for [devise](https://github.com
|
|
24
24
|
## Installation
|
25
25
|
|
26
26
|
```ruby
|
27
|
-
gem 'warden-jwt_auth', '~> 0.2.
|
27
|
+
gem 'warden-jwt_auth', '~> 0.2.1'
|
28
28
|
```
|
29
29
|
|
30
30
|
And then execute:
|
@@ -63,7 +63,7 @@ Currently, HS256 algorithm is the one in use.
|
|
63
63
|
|
64
64
|
### Warden scopes configuration
|
65
65
|
|
66
|
-
You have to map the warden scopes that will be authenticatable through JWT, with the user repositories from where these scope user records can be fetched.
|
66
|
+
You have to map the warden scopes that will be authenticatable through JWT, with the user repositories from where these scope user records can be fetched. If a string is supplied, the user repository will first be looked up as a constant.
|
67
67
|
|
68
68
|
For instance:
|
69
69
|
|
@@ -142,7 +142,7 @@ config.revocation_requests = [
|
|
142
142
|
|
143
143
|
**Important**: You are encouraged to delimit your regular expression with `^` and `$` to avoid unintentional matches.
|
144
144
|
|
145
|
-
Besides, you need to configure which revocation strategy will be used for each scope.
|
145
|
+
Besides, you need to configure which revocation strategy will be used for each scope. If a string is supplied, the revocation strategy will first be looked up as a constant.
|
146
146
|
|
147
147
|
```ruby
|
148
148
|
config.revocation_strategies = { user: RevocationStrategy }
|
data/lib/warden/jwt_auth.rb
CHANGED
@@ -25,7 +25,8 @@ module Warden
|
|
25
25
|
# Expiration time for tokens
|
26
26
|
setting :expiration_time, 3600
|
27
27
|
|
28
|
-
# A hash of warden scopes as keys and user repositories as values.
|
28
|
+
# A hash of warden scopes as keys and user repositories as values. The
|
29
|
+
# values can be either the constants themselves or the constant names.
|
29
30
|
#
|
30
31
|
# @see Interfaces::UserRepository
|
31
32
|
# @see Interfaces::User
|
@@ -56,8 +57,9 @@ module Warden
|
|
56
57
|
upcase_first_items(value)
|
57
58
|
end
|
58
59
|
|
59
|
-
# Hash with scopes as keys and
|
60
|
-
#
|
60
|
+
# Hash with scopes as keys and strategies to revoke tokens for that scope
|
61
|
+
# as values. The values can be either the constants themselves or the
|
62
|
+
# constant names.
|
61
63
|
#
|
62
64
|
# @example
|
63
65
|
# {
|
@@ -87,12 +89,30 @@ module Warden
|
|
87
89
|
end
|
88
90
|
|
89
91
|
Import = Dry::AutoInject(config)
|
92
|
+
|
93
|
+
config.instance_eval do
|
94
|
+
def mappings
|
95
|
+
constantize_values(super)
|
96
|
+
end
|
97
|
+
|
98
|
+
def revocation_strategies
|
99
|
+
constantize_values(super)
|
100
|
+
end
|
101
|
+
|
102
|
+
# :reek:UtilityFunction
|
103
|
+
def constantize_values(hash)
|
104
|
+
hash.each_with_object({}) do |(key, value), memo|
|
105
|
+
memo[key] = value.is_a?(String) ? Object.const_get(value) : value
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
90
109
|
end
|
91
110
|
end
|
92
111
|
|
93
112
|
require 'warden/jwt_auth/version'
|
94
113
|
require 'warden/jwt_auth/header_parser'
|
95
114
|
require 'warden/jwt_auth/payload_user_helper'
|
115
|
+
require 'warden/jwt_auth/env_helper'
|
96
116
|
require 'warden/jwt_auth/user_encoder'
|
97
117
|
require 'warden/jwt_auth/user_decoder'
|
98
118
|
require 'warden/jwt_auth/token_encoder'
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Warden
|
4
|
+
module JWTAuth
|
5
|
+
# Helper functions to centralize working with rack env.
|
6
|
+
#
|
7
|
+
# It follows
|
8
|
+
# [rack](http://www.rubydoc.info/github/rack/rack/file/SPEC#The_Environment)
|
9
|
+
# and [PEP 333](https://www.python.org/dev/peps/pep-0333/#environ-variables)
|
10
|
+
# conventions.
|
11
|
+
module EnvHelper
|
12
|
+
# Returns PATH_INFO environment variable
|
13
|
+
#
|
14
|
+
# @param env [Hash] Rack env
|
15
|
+
# @return [String]
|
16
|
+
def self.path_info(env)
|
17
|
+
env['PATH_INFO'] || ''
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns REQUEST_METHOD environment variable
|
21
|
+
#
|
22
|
+
# @param env [Hash] Rack env
|
23
|
+
# @return [String]
|
24
|
+
def self.request_method(env)
|
25
|
+
env['REQUEST_METHOD']
|
26
|
+
end
|
27
|
+
|
28
|
+
# Returns HTTP_AUTHORIZATION environment variable
|
29
|
+
#
|
30
|
+
# @param env [Hash] Rack env
|
31
|
+
# @return [String]
|
32
|
+
def self.authorization_header(env)
|
33
|
+
env['HTTP_AUTHORIZATION']
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns a copy of `env` with value added to the `HTTP_AUTHORIZATION`
|
37
|
+
# environment variable.
|
38
|
+
#
|
39
|
+
# Be aware than `env` is not modified in place and still an updated copy
|
40
|
+
# is returned.
|
41
|
+
#
|
42
|
+
# @param env [Hash] Rack env
|
43
|
+
# @param value [String]
|
44
|
+
# @return [Hash] modified rack env
|
45
|
+
def self.set_authorization_header(env, value)
|
46
|
+
env = env.dup
|
47
|
+
env['HTTP_AUTHORIZATION'] = value
|
48
|
+
env
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -14,7 +14,7 @@ module Warden
|
|
14
14
|
# @return [String] JWT token
|
15
15
|
# @return [nil] if token is not present
|
16
16
|
def self.from_env(env)
|
17
|
-
auth = env
|
17
|
+
auth = EnvHelper.authorization_header(env)
|
18
18
|
return nil unless auth
|
19
19
|
method, token = auth.split
|
20
20
|
method == METHOD ? token : nil
|
@@ -27,9 +27,7 @@ module Warden
|
|
27
27
|
# @param token [String] JWT token
|
28
28
|
# @return [Hash] modified rack env
|
29
29
|
def self.to_env(env, token)
|
30
|
-
env
|
31
|
-
env['HTTP_AUTHORIZATION'] = "#{METHOD} #{token}"
|
32
|
-
env
|
30
|
+
EnvHelper.set_authorization_header(env, "#{METHOD} #{token}")
|
33
31
|
end
|
34
32
|
|
35
33
|
# Returns a copy of headers with token added in the `Authorization` key.
|
@@ -29,7 +29,9 @@ module Warden
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def token_should_be_added?(scope, env)
|
32
|
-
|
32
|
+
path_info = EnvHelper.path_info(env)
|
33
|
+
method = EnvHelper.request_method(env)
|
34
|
+
jwt_scope?(scope) && request_matches?(path_info, method)
|
33
35
|
end
|
34
36
|
|
35
37
|
def jwt_scope?(scope)
|
@@ -37,12 +39,12 @@ module Warden
|
|
37
39
|
jwt_scopes.include?(scope)
|
38
40
|
end
|
39
41
|
|
40
|
-
# :reek:
|
41
|
-
def request_matches?(
|
42
|
+
# :reek:ControlParameter
|
43
|
+
def request_matches?(path_info, method)
|
42
44
|
dispatch_requests.each do |tuple|
|
43
|
-
|
44
|
-
return true if
|
45
|
-
|
45
|
+
dispatch_method, dispatch_path = tuple
|
46
|
+
return true if path_info.match(dispatch_path) &&
|
47
|
+
method == dispatch_method
|
46
48
|
end
|
47
49
|
false
|
48
50
|
end
|
@@ -8,11 +8,12 @@ module Warden
|
|
8
8
|
# Debugging key added to `env`
|
9
9
|
ENV_KEY = 'warden-jwt_auth.revocation_manager'
|
10
10
|
|
11
|
-
attr_reader :app, :config
|
11
|
+
attr_reader :app, :config, :helper
|
12
12
|
|
13
13
|
def initialize(app)
|
14
14
|
@app = app
|
15
15
|
@config = JWTAuth.config
|
16
|
+
@helper = EnvHelper
|
16
17
|
end
|
17
18
|
|
18
19
|
def call(env)
|
@@ -26,17 +27,19 @@ module Warden
|
|
26
27
|
|
27
28
|
def revoke_token(env)
|
28
29
|
token = HeaderParser.from_env(env)
|
29
|
-
|
30
|
+
path_info = EnvHelper.path_info(env)
|
31
|
+
method = EnvHelper.request_method(env)
|
32
|
+
return unless token && token_should_be_revoked?(path_info, method)
|
30
33
|
TokenRevoker.new.call(token)
|
31
34
|
end
|
32
35
|
|
33
|
-
# :reek:
|
34
|
-
def token_should_be_revoked?(
|
36
|
+
# :reek:ControlParameter
|
37
|
+
def token_should_be_revoked?(path_info, method)
|
35
38
|
revocation_requests = config.revocation_requests
|
36
39
|
revocation_requests.each do |tuple|
|
37
|
-
|
38
|
-
return true if
|
39
|
-
|
40
|
+
revocation_method, revocation_path = tuple
|
41
|
+
return true if path_info.match(revocation_path) &&
|
42
|
+
method == revocation_method
|
40
43
|
end
|
41
44
|
false
|
42
45
|
end
|
@@ -8,7 +8,7 @@ module Warden
|
|
8
8
|
# `Authorization` request header
|
9
9
|
# :reek:PrimaDonnaMethod
|
10
10
|
class Strategy < Warden::Strategies::Base
|
11
|
-
# :reek:
|
11
|
+
# :reek:NilCheck
|
12
12
|
def valid?
|
13
13
|
!token.nil?
|
14
14
|
end
|
@@ -20,8 +20,8 @@ module Warden
|
|
20
20
|
def authenticate!
|
21
21
|
user = UserDecoder.new.call(token, scope)
|
22
22
|
success!(user)
|
23
|
-
rescue JWT::DecodeError =>
|
24
|
-
fail!(
|
23
|
+
rescue JWT::DecodeError => exception
|
24
|
+
fail!(exception.message)
|
25
25
|
end
|
26
26
|
|
27
27
|
private
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: warden-jwt_auth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marc Busqué
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-12-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dry-configurable
|
@@ -191,6 +191,7 @@ files:
|
|
191
191
|
- bin/setup
|
192
192
|
- docker-compose.yml
|
193
193
|
- lib/warden/jwt_auth.rb
|
194
|
+
- lib/warden/jwt_auth/env_helper.rb
|
194
195
|
- lib/warden/jwt_auth/errors.rb
|
195
196
|
- lib/warden/jwt_auth/header_parser.rb
|
196
197
|
- lib/warden/jwt_auth/hooks.rb
|