fb-jwt-auth 0.2.0 → 0.5.0

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
  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