epb-auth-tools 1.0.7 → 1.0.11
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/lib/epb-auth-tools.rb +5 -5
- data/lib/errors.rb +15 -0
- data/lib/http_client.rb +7 -5
- data/lib/sinatra/conditional.rb +2 -2
- data/lib/token.rb +11 -15
- data/lib/token_processor.rb +6 -8
- metadata +17 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 98143d27f89eda42d073be36aeebd2fa9820218f27a7448faaf2c968f22fe74e
|
4
|
+
data.tar.gz: 5baa025fef34595bed597a7ac79e1b9097a263d6d42c1112431923b9d26b041e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3bb82ad8a2b5e383cdc319a308833ea773a5ca02cb6cee35bad542109b1e4583f6616e631f9afbde756d44408be8827783160c51a9312c85c8e88fa7914eeabb
|
7
|
+
data.tar.gz: 380e83b5a4cd97cb55234df83c2eb3c1fbf006656266a49d31f59cf60d11ced9b9939071707246fe3ffcb9051e863cb4f5af767f0d54bd3418e52bee204d4e5b
|
data/lib/epb-auth-tools.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Auth
|
4
|
-
require_relative
|
5
|
-
require_relative
|
6
|
-
require_relative
|
7
|
-
require_relative
|
4
|
+
require_relative "errors"
|
5
|
+
require_relative "http_client"
|
6
|
+
require_relative "token"
|
7
|
+
require_relative "token_processor"
|
8
8
|
|
9
|
-
require_relative
|
9
|
+
require_relative "sinatra/conditional"
|
10
10
|
end
|
data/lib/errors.rb
CHANGED
@@ -7,8 +7,10 @@ module Auth
|
|
7
7
|
|
8
8
|
class Processor < Auth::Errors::Error
|
9
9
|
end
|
10
|
+
|
10
11
|
class ProcessorHasNoSecret < Auth::Errors::Error
|
11
12
|
end
|
13
|
+
|
12
14
|
class ProcessorHasNoIssuer < Auth::Errors::Error
|
13
15
|
end
|
14
16
|
|
@@ -17,25 +19,34 @@ module Auth
|
|
17
19
|
|
18
20
|
class TokenMissing < Auth::Errors::Token
|
19
21
|
end
|
22
|
+
|
20
23
|
class TokenPayloadError < Auth::Errors::Token
|
21
24
|
end
|
25
|
+
|
22
26
|
class TokenExpired < Auth::Errors::TokenPayloadError
|
23
27
|
end
|
28
|
+
|
24
29
|
class TokenNotYetValid < Auth::Errors::TokenPayloadError
|
25
30
|
end
|
31
|
+
|
26
32
|
class TokenHasNoIssuer < Auth::Errors::TokenPayloadError
|
27
33
|
end
|
34
|
+
|
28
35
|
class TokenHasNoSubject < Auth::Errors::TokenPayloadError
|
29
36
|
end
|
37
|
+
|
30
38
|
class TokenHasNoIssuedAt < Auth::Errors::TokenPayloadError
|
31
39
|
end
|
40
|
+
|
32
41
|
class TokenHasNoExpiry < Auth::Errors::TokenPayloadError
|
33
42
|
end
|
43
|
+
|
34
44
|
class TokenIssuerIncorrect < Auth::Errors::TokenPayloadError
|
35
45
|
end
|
36
46
|
|
37
47
|
class TokenDecodeError < Auth::Errors::Token
|
38
48
|
end
|
49
|
+
|
39
50
|
class TokenTamperDetected < Auth::Errors::TokenDecodeError
|
40
51
|
end
|
41
52
|
|
@@ -44,15 +55,19 @@ module Auth
|
|
44
55
|
|
45
56
|
class ClientHasNoAuthServer < Auth::Errors::Client
|
46
57
|
end
|
58
|
+
|
47
59
|
class ClientHasNoClientId < Auth::Errors::Client
|
48
60
|
end
|
61
|
+
|
49
62
|
class ClientHasNoClientSecret < Auth::Errors::Client
|
50
63
|
end
|
64
|
+
|
51
65
|
class ClientHasNoBaseUri < Auth::Errors::Client
|
52
66
|
end
|
53
67
|
|
54
68
|
class Network < Auth::Errors::Error
|
55
69
|
end
|
70
|
+
|
56
71
|
class NetworkConnectionFailed < Auth::Errors::Network
|
57
72
|
end
|
58
73
|
end
|
data/lib/http_client.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "oauth2"
|
4
4
|
|
5
5
|
module Auth
|
6
6
|
class HttpClient
|
@@ -21,14 +21,15 @@ module Auth
|
|
21
21
|
@authenticated_client = nil
|
22
22
|
|
23
23
|
site_url = URI.parse(auth_server)
|
24
|
-
token_url = site_url.path
|
25
|
-
authorisation_url = site_url.path
|
24
|
+
token_url = "#{site_url.path}/oauth/token"
|
25
|
+
authorisation_url = "#{site_url.path}/oauth/token"
|
26
26
|
site_url = "#{site_url.scheme}://#{site_url.host}:#{site_url.port}"
|
27
27
|
|
28
28
|
@base_uri = base_uri
|
29
29
|
@client =
|
30
30
|
auth_client.new client_id,
|
31
31
|
client_secret,
|
32
|
+
auth_scheme: :request_body,
|
32
33
|
site: site_url,
|
33
34
|
token_url: token_url,
|
34
35
|
authorisation_url: authorisation_url,
|
@@ -60,8 +61,9 @@ module Auth
|
|
60
61
|
|
61
62
|
if @authenticated_client.respond_to? method_name
|
62
63
|
response = @authenticated_client.send method_name, *args, &block
|
63
|
-
if response.
|
64
|
-
|
64
|
+
if response.status == 401
|
65
|
+
# a 401 here is assumed to be due to an expired token
|
66
|
+
# otherwise, refreshing the token and calling again should make no difference to the ultimate response
|
65
67
|
refresh
|
66
68
|
response = @authenticated_client.send method_name, *args, &block
|
67
69
|
end
|
data/lib/sinatra/conditional.rb
CHANGED
@@ -4,9 +4,9 @@ module Auth
|
|
4
4
|
module Sinatra
|
5
5
|
class Conditional
|
6
6
|
def self.process_request(env)
|
7
|
-
jwt_token = env.fetch(
|
7
|
+
jwt_token = env.fetch("HTTP_AUTHORIZATION", "").slice(7..-1)
|
8
8
|
processor =
|
9
|
-
Auth::TokenProcessor.new ENV[
|
9
|
+
Auth::TokenProcessor.new ENV["JWT_SECRET"], ENV["JWT_ISSUER"]
|
10
10
|
processor.process jwt_token
|
11
11
|
end
|
12
12
|
end
|
data/lib/token.rb
CHANGED
@@ -8,38 +8,34 @@ module Auth
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def sub
|
11
|
-
@payload[
|
11
|
+
@payload["sub"]
|
12
12
|
end
|
13
13
|
|
14
14
|
def scope?(scope)
|
15
|
-
@payload[
|
15
|
+
@payload["scopes"]&.include? scope
|
16
16
|
end
|
17
17
|
|
18
18
|
def scopes?(scopes)
|
19
|
-
scopes.all? { |scope| @payload[
|
19
|
+
scopes.all? { |scope| @payload["scopes"]&.include? scope }
|
20
20
|
end
|
21
21
|
|
22
22
|
def supplemental(property = nil)
|
23
|
-
unless property.nil? || @payload[
|
24
|
-
return @payload['sup'][property]
|
25
|
-
end
|
23
|
+
return @payload["sup"][property] unless property.nil? || @payload["sup"][property].nil?
|
26
24
|
|
27
|
-
@payload[
|
25
|
+
@payload["sup"]
|
28
26
|
end
|
29
27
|
|
30
28
|
def encode(jwt_secret)
|
31
|
-
JWT.encode @payload, jwt_secret,
|
29
|
+
JWT.encode @payload, jwt_secret, "HS256"
|
32
30
|
end
|
33
31
|
|
34
|
-
|
32
|
+
private
|
35
33
|
|
36
34
|
def validate_payload
|
37
|
-
raise Auth::Errors::TokenHasNoIssuer unless @payload.key?(
|
38
|
-
raise Auth::Errors::TokenHasNoIssuedAt unless @payload.key?(
|
39
|
-
unless @payload[
|
40
|
-
|
41
|
-
end
|
42
|
-
raise Auth::Errors::TokenHasNoSubject unless @payload.key?('sub')
|
35
|
+
raise Auth::Errors::TokenHasNoIssuer unless @payload.key?("iss")
|
36
|
+
raise Auth::Errors::TokenHasNoIssuedAt unless @payload.key?("iat")
|
37
|
+
raise Auth::Errors::TokenNotYetValid unless @payload["iat"] <= Time.now.to_i
|
38
|
+
raise Auth::Errors::TokenHasNoSubject unless @payload.key?("sub")
|
43
39
|
end
|
44
40
|
end
|
45
41
|
end
|
data/lib/token_processor.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "jwt"
|
4
4
|
|
5
5
|
module Auth
|
6
6
|
class TokenProcessor
|
@@ -17,19 +17,17 @@ module Auth
|
|
17
17
|
|
18
18
|
payload, _header = jwt_process token
|
19
19
|
|
20
|
-
raise Auth::Errors::TokenExpired unless payload.key?(
|
21
|
-
raise Auth::Errors::TokenHasNoIssuer unless payload.key?(
|
22
|
-
unless payload[
|
23
|
-
raise Auth::Errors::TokenIssuerIncorrect
|
24
|
-
end
|
20
|
+
raise Auth::Errors::TokenExpired unless payload.key?("exp")
|
21
|
+
raise Auth::Errors::TokenHasNoIssuer unless payload.key?("iss")
|
22
|
+
raise Auth::Errors::TokenIssuerIncorrect unless payload["iss"] == @jwt_issuer
|
25
23
|
|
26
24
|
Auth::Token.new payload
|
27
25
|
end
|
28
26
|
|
29
|
-
|
27
|
+
private
|
30
28
|
|
31
29
|
def jwt_process(token)
|
32
|
-
options = { algorithm:
|
30
|
+
options = { algorithm: "HS256", iss: @jwt_issuer }
|
33
31
|
|
34
32
|
JWT.decode token, @jwt_secret, true, options
|
35
33
|
rescue JWT::ExpiredSignature
|
metadata
CHANGED
@@ -1,17 +1,19 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: epb-auth-tools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lawrence Goldstien <lawrence.goldstien@madetech.com>
|
8
8
|
- Yusuf Sheikh <yusuf@madetech.com>
|
9
9
|
- Jaseera <jaseera@madetech.com>
|
10
|
-
- Kevin Keenoy <kevin.keenoy@
|
10
|
+
- Kevin Keenoy <kevin.keenoy@levellingup.gov.uk>
|
11
|
+
- Douglas Greenshields <douglas.greenshields@levellingup.gov.uk>
|
12
|
+
- Aga Dufrat <aga.dufrat@levellingup.gov.uk>
|
11
13
|
autorequire:
|
12
14
|
bindir: bin
|
13
15
|
cert_chain: []
|
14
|
-
date:
|
16
|
+
date: 2022-08-23 00:00:00.000000000 Z
|
15
17
|
dependencies:
|
16
18
|
- !ruby/object:Gem::Dependency
|
17
19
|
name: jwt
|
@@ -19,28 +21,34 @@ dependencies:
|
|
19
21
|
requirements:
|
20
22
|
- - "~>"
|
21
23
|
- !ruby/object:Gem::Version
|
22
|
-
version: '2.
|
24
|
+
version: '2.3'
|
23
25
|
type: :runtime
|
24
26
|
prerelease: false
|
25
27
|
version_requirements: !ruby/object:Gem::Requirement
|
26
28
|
requirements:
|
27
29
|
- - "~>"
|
28
30
|
- !ruby/object:Gem::Version
|
29
|
-
version: '2.
|
31
|
+
version: '2.3'
|
30
32
|
- !ruby/object:Gem::Dependency
|
31
33
|
name: oauth2
|
32
34
|
requirement: !ruby/object:Gem::Requirement
|
33
35
|
requirements:
|
34
|
-
- - "
|
36
|
+
- - ">="
|
35
37
|
- !ruby/object:Gem::Version
|
36
38
|
version: '1.4'
|
39
|
+
- - "<"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '3.0'
|
37
42
|
type: :runtime
|
38
43
|
prerelease: false
|
39
44
|
version_requirements: !ruby/object:Gem::Requirement
|
40
45
|
requirements:
|
41
|
-
- - "
|
46
|
+
- - ">="
|
42
47
|
- !ruby/object:Gem::Version
|
43
48
|
version: '1.4'
|
49
|
+
- - "<"
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '3.0'
|
44
52
|
description:
|
45
53
|
email:
|
46
54
|
executables: []
|
@@ -65,14 +73,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
65
73
|
requirements:
|
66
74
|
- - ">="
|
67
75
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
76
|
+
version: 2.7.0
|
69
77
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
78
|
requirements:
|
71
79
|
- - ">="
|
72
80
|
- !ruby/object:Gem::Version
|
73
81
|
version: '0'
|
74
82
|
requirements: []
|
75
|
-
rubygems_version: 3.
|
83
|
+
rubygems_version: 3.3.7
|
76
84
|
signing_key:
|
77
85
|
specification_version: 4
|
78
86
|
summary: Tools for authentication and authorisation with JWTs and OAuth
|