fb-jwt-auth 0.2.0 → 0.5.0

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
  SHA256:
3
- metadata.gz: f86d88c60d096a604b4c0e3bd40acb9e6869c99011f91f14eb9488b7e9d4f4ae
4
- data.tar.gz: f79a60753d8fee05024b3303a6d03d1fb28d13db6d788a3b3ca24e2c16a8707f
3
+ metadata.gz: d2a0ab54dae6b316b53e5518a6e85e0fd9da9608a68be9cf3e153755b1f3a5d8
4
+ data.tar.gz: f41116c14483ef87b5be6ea47632d0eb634c748ea273e4e3b108ea94afb4ec32
5
5
  SHA512:
6
- metadata.gz: 52b523c492ba637761d84f15c0d374e1920d1c0e7210cf8fbbfefee2df9efcee10abaf75a6f9942266794c509616717da55cadb38916c48d31372cb0c7b92c6f
7
- data.tar.gz: 9870d7e4d6854fb21cc07fc8903661fca1fac308ce716866bd2d9bbee95fdfafe32deb47c3f54fbb14112ae88b25e2262fbec35ebe34a5d0ddd95de8f40c20ee
6
+ metadata.gz: 4245369f210cb3f722308859890d81fa0c3c2cf76dad469c0cbad3aa563d06a0576248bc13cb609179fe1376c5de661b644d9e62d8f7245e546ce172d352d642
7
+ data.tar.gz: 957cb3c0640e3f173c2c8683f54d5de37acd9ba35194973c7cb3fa7822eae21104aadab615dfc97c3638087df245f40c40d2fc15fb94a037bf76280e0699d7f8
data/.gitignore CHANGED
@@ -11,3 +11,4 @@
11
11
  .rspec_status
12
12
  Gemfile.lock
13
13
  .byebug_history
14
+ *.gem
@@ -1,3 +1,18 @@
1
+ # 0.5.0
2
+ * Do not base64 decode private key
3
+
4
+ # 0.4.0
5
+ * Generate the access token
6
+
7
+ # 0.3.0
8
+ * Request non cached version of public key if first validition fails
9
+
10
+ # v0.2.2
11
+ * Add token not present exception when token is empty
12
+
13
+ # v0.2.1
14
+ * Add better error messages
15
+
1
16
  # v0.2.0
2
17
 
3
18
  * Add service token cache v3 implementation
data/README.md CHANGED
@@ -25,6 +25,16 @@ Fb::Jwt::Auth.configure do |config|
25
25
  config.service_token_cache_root_url = ENV['SERVICE_TOKEN_CACHE_ROOT_URL']
26
26
  end
27
27
  ```
28
+ In order to generate the service access token we need to use `Fb::Jwt::Auth::ServiceAccessToken.new.generate` or if you require a subject, `Fb::Jwt::Auth::ServiceAccessToken.new(subject: subject).generate`
29
+
30
+ In the case you need to configure the service access token as a client
31
+ ```ruby
32
+ Fb::Jwt::Auth.configure do |config|
33
+ config.issuer = 'fb-editor'
34
+ config.namespace = 'formbuilder-saas-test'
35
+ config.encoded_private_key = 'base64 encoded private key'
36
+ end
37
+ ```
28
38
 
29
39
  ### Using other endpoint versions
30
40
 
@@ -1,18 +1,23 @@
1
1
  require 'fb/jwt/auth/version'
2
2
  require 'openssl'
3
3
  require 'jwt'
4
- require 'active_support/core_ext'
4
+ require 'active_support/all'
5
5
 
6
6
  module Fb
7
7
  module Jwt
8
8
  class Auth
9
- cattr_accessor :service_token_cache_root_url, :service_token_cache_api_version
9
+ cattr_accessor :service_token_cache_root_url,
10
+ :service_token_cache_api_version,
11
+ :encoded_private_key,
12
+ :issuer,
13
+ :namespace
10
14
 
11
15
  def self.configure(&block)
12
16
  yield self
13
17
  end
14
18
 
15
19
  autoload :ServiceTokenClient, 'fb/jwt/auth/service_token_client'
20
+ autoload :ServiceAccessToken, 'fb/jwt/auth/service_access_token'
16
21
 
17
22
  class TokenNotPresentError < StandardError
18
23
  end
@@ -39,15 +44,14 @@ module Fb
39
44
  end
40
45
 
41
46
  def verify!
42
- raise TokenNotPresentError if token.nil?
47
+ raise TokenNotPresentError.new('Token is not present') if token.blank?
43
48
 
44
49
  application_details = find_application_info
45
50
 
46
51
  begin
47
- hmac_secret = public_key(application_details)
48
- payload, _header = decode(hmac_secret: hmac_secret)
52
+ payload, _header = retrieve_and_decode_public_key(application_details)
49
53
  rescue StandardError => e
50
- error_message = "Couldn't parse that token - error #{e}"
54
+ error_message = "Token is not valid: error #{e}"
51
55
  logger.debug(error_message)
52
56
  raise TokenNotValidError.new(error_message)
53
57
  end
@@ -57,7 +61,7 @@ module Fb
57
61
  iat_skew = payload['iat'].to_i - Time.zone.now.to_i
58
62
 
59
63
  if iat_skew.abs > leeway.to_i
60
- error_message = "iat skew is #{iat_skew}, max is #{leeway} - INVALID"
64
+ error_message = "Token has expired: iat skew is #{iat_skew}, max is #{leeway}"
61
65
  logger.debug(error_message)
62
66
 
63
67
  raise TokenExpiredError.new(error_message)
@@ -67,6 +71,15 @@ module Fb
67
71
  payload
68
72
  end
69
73
 
74
+ def retrieve_and_decode_public_key(application_details)
75
+ hmac_secret = public_key(application_details)
76
+ decode(hmac_secret: hmac_secret)
77
+ rescue JWT::VerificationError
78
+ logger.debug('First validation failed. Requesting non cached public key')
79
+ hmac_secret = public_key(application_details.merge(ignore_cache: true))
80
+ decode(hmac_secret: hmac_secret)
81
+ end
82
+
70
83
  def decode(verify: true, hmac_secret: nil)
71
84
  JWT.decode(
72
85
  token,
@@ -84,8 +97,8 @@ module Fb
84
97
  application = payload['iss']
85
98
  namespace = payload['namespace']
86
99
 
87
- raise IssuerNotPresentError unless application
88
- raise NamespaceNotPresentError unless namespace
100
+ raise IssuerNotPresentError.new('Issuer is not present in the token') unless application
101
+ raise NamespaceNotPresentError.new('Namespace is not present in the token') unless namespace
89
102
 
90
103
  { application: application, namespace: namespace}
91
104
  end
@@ -0,0 +1,43 @@
1
+ module Fb
2
+ module Jwt
3
+ class Auth
4
+ class ServiceAccessToken
5
+ attr_reader :encoded_private_key,
6
+ :issuer,
7
+ :subject,
8
+ :namespace
9
+
10
+ def initialize(subject: nil)
11
+ @subject = subject
12
+ @encoded_private_key = Fb::Jwt::Auth.encoded_private_key
13
+ @namespace = Fb::Jwt::Auth.namespace
14
+ @issuer = Fb::Jwt::Auth.issuer
15
+ end
16
+
17
+ def generate
18
+ return '' if encoded_private_key.blank?
19
+
20
+ private_key = OpenSSL::PKey::RSA.new(encoded_private_key.chomp)
21
+
22
+ JWT.encode(
23
+ token,
24
+ private_key,
25
+ 'RS256'
26
+ )
27
+ end
28
+
29
+ private
30
+
31
+ def token
32
+ payload = {
33
+ iss: issuer,
34
+ iat: Time.current.to_i
35
+ }
36
+ payload[:sub] = subject if subject.present?
37
+ payload[:namespace] = namespace if namespace.present?
38
+ payload
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -12,9 +12,10 @@ class Fb::Jwt::Auth::ServiceTokenClient
12
12
 
13
13
  attr_accessor :application, :namespace, :root_url, :api_version
14
14
 
15
- def initialize(application:, namespace: nil)
15
+ def initialize(application:, namespace: nil, ignore_cache: false)
16
16
  @application = application
17
17
  @namespace = namespace
18
+ @ignore_cache = ignore_cache
18
19
  @root_url = Fb::Jwt::Auth.service_token_cache_root_url
19
20
  @api_version = Fb::Jwt::Auth.service_token_cache_api_version || :v2
20
21
  end
@@ -38,8 +39,14 @@ class Fb::Jwt::Auth::ServiceTokenClient
38
39
 
39
40
  private
40
41
 
42
+ attr_reader :ignore_cache
43
+
41
44
  def public_key_uri
42
- URI.join(root_url, version_url)
45
+ URI.join(root_url, "#{version_url}#{query_param}")
46
+ end
47
+
48
+ def query_param
49
+ ignore_cache ? '?ignore_cache=true' : ''
43
50
  end
44
51
 
45
52
  def version_url
@@ -1,7 +1,7 @@
1
1
  module Fb
2
2
  module Jwt
3
3
  class Auth
4
- VERSION = "0.2.0"
4
+ VERSION = "0.5.0"
5
5
  end
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fb-jwt-auth
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Form builder developers
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-10-23 00:00:00.000000000 Z
11
+ date: 2021-01-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jwt
@@ -73,6 +73,7 @@ files:
73
73
  - bin/setup
74
74
  - fb-jwt-auth.gemspec
75
75
  - lib/fb/jwt/auth.rb
76
+ - lib/fb/jwt/auth/service_access_token.rb
76
77
  - lib/fb/jwt/auth/service_token_client.rb
77
78
  - lib/fb/jwt/auth/version.rb
78
79
  homepage: https://github.com/ministryofjustice/fb-jwt-auth