moj-simple-jwt-auth 0.0.1 → 0.2.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: '069216a49c032609b1b2d4bb2b9fa9841efb7ff086d6eabec5f5f3394be7c6f7'
4
- data.tar.gz: 6d6571c76a08ca15844b6e3251f900f53fcdcf981b90f3a5509835b80acf4306
3
+ metadata.gz: 60dcec9d18f24f29367e1d83d17c3c3309ec1ca09bc556390181b05bda6f7279
4
+ data.tar.gz: 981c1cd77b2e674184d07b4ca70c3c87657f8c4ec5e997a44c05f1ae8fabf08a
5
5
  SHA512:
6
- metadata.gz: 1dfe076548da296f2233ae2b1103c01e5dad5940cbd6a2133b35258f41a24b36fe785681f940d191c57f3a1d92de96dbd968746a986f3e2a958e8150552644da
7
- data.tar.gz: ff1c2a743a8f8d03c2a3f9d61cf8ba423e38fbd3b07847a85c7e78d5cd04c81c74615ee39baab1a3af233c87c87fb0651a9e95c873feb1336bbf4731d0aeb76e
6
+ metadata.gz: aa4da80b4fef3838177b572d7c8b257a9827a51ad2435f4e85dc030403bd0c2f7704fbd4aa1250526f1489f41f48140683431bb8bea78b40f1c77f97ac259e62
7
+ data.tar.gz: 13b5b74a4e4e9a43d2b45480077676d9c9331785709310241c017e93995ed96aca8771ae115f194da36422ea70fc9fc6c13fc1c94b1bb6c8a313e72346c40549
@@ -13,7 +13,7 @@ jobs:
13
13
  strategy:
14
14
  fail-fast: false
15
15
  matrix:
16
- ruby: ['3.0.4', '3.1.2']
16
+ ruby: ['3.3', '3.4', '3.5']
17
17
 
18
18
  steps:
19
19
  - uses: actions/checkout@v3
data/.rubocop.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  AllCops:
2
- TargetRubyVersion: 3.0
2
+ TargetRubyVersion: 3.3
3
3
  SuggestExtensions: false
4
4
  NewCops: enable
5
5
  Exclude:
data/README.md CHANGED
@@ -36,6 +36,37 @@ For the **producer** side (the API service for instance) you will need to config
36
36
 
37
37
  There are several options you can configure, like expiration, leeway, logging, and more. Please refer to the [Configuration class](lib/simple_jwt_auth/configuration.rb) for more details.
38
38
 
39
+ ### Example of token
40
+
41
+ This is a valid format token (might become invalid due to expiration at some point):
42
+
43
+ `eyJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE2ODI1OTMwMzAsImV4cCI6MTY5ODQwNDU1NSwiaXNzIjoiY3JpbWUtYXBwbHkifQ.x2UE5VnwN5mf8elByPBnjiNChvsySqDjiLht6eN3ZPY`
44
+
45
+ It has 3 parts, separated by dots, base64-encoded:
46
+
47
+ 1. Header (`eyJhbGciOiJIUzI1NiJ9`), containing the algorithm used. No other details are needed.
48
+ ```json
49
+ {
50
+ "alg": "HS256"
51
+ }
52
+ ```
53
+
54
+ 2. Payload (`eyJpYXQiOjE2ODI1OTMwMzAsImV4cCI6MTY5ODQwNDU1NSwiaXNzIjoiY3JpbWUtYXBwbHkifQ`), with some mandatory details.
55
+ ```json
56
+ {
57
+ "iat": 1682593030,
58
+ "exp": 1698404555,
59
+ "iss": "crime-apply"
60
+ }
61
+ ```
62
+ *iat* is the issued at seconds since epoch, *exp* is the expire at seconds since epoch, and finally *iss* is the issuer identifier or the name of the consumer to whom this token belongs.
63
+
64
+ 3. Signature (`x2UE5VnwN5mf8elByPBnjiNChvsySqDjiLht6eN3ZPY`)
65
+
66
+ To create the signature part you have to take the encoded header, the encoded payload, a secret, the algorithm specified in the header, and sign that.
67
+
68
+ The token must be included in each request, in an Authorization header (bearer).
69
+
39
70
  ## Development
40
71
 
41
72
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rake` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -2,7 +2,10 @@
2
2
 
3
3
  module SimpleJwtAuth
4
4
  module Errors
5
- class UndefinedIssuer < StandardError; end
6
- class UnknownIssuer < StandardError; end
5
+ class Forbidden < StandardError; end
6
+ class IssuerError < StandardError; end
7
+
8
+ class UndefinedIssuer < IssuerError; end
9
+ class UnknownIssuer < IssuerError; end
7
10
  end
8
11
  end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SimpleJwtAuth
4
+ module Middleware
5
+ module Grape
6
+ class Authorisation < ::Grape::Middleware::Base
7
+ def initialize(app, options = nil)
8
+ super(app, **(options || {}))
9
+ end
10
+
11
+ def before
12
+ return if test_env? || consumer_authorised?
13
+
14
+ raise SimpleJwtAuth::Errors::Forbidden,
15
+ "access to endpoint forbidden for issuer `#{current_issuer}`"
16
+ end
17
+
18
+ private
19
+
20
+ def test_env?
21
+ env['rack.test'] == true
22
+ end
23
+
24
+ def consumer_authorised?
25
+ route_authorised_consumers.include?(current_issuer) ||
26
+ route_authorised_consumers.include?('*')
27
+ end
28
+
29
+ def route_authorised_consumers
30
+ context.route.settings.fetch(:authorised_consumers, [])
31
+ end
32
+
33
+ def current_issuer
34
+ env.fetch(Jwt::ENV_PAYLOAD_KEY, {})['iss']
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -3,10 +3,15 @@
3
3
  module SimpleJwtAuth
4
4
  module Middleware
5
5
  module Grape
6
- class Jwt < ::Grape::Middleware::Auth::Base
6
+ class Jwt < ::Grape::Middleware::Base
7
7
  ENV_AUTH_KEY = 'HTTP_AUTHORIZATION'
8
8
  ENV_PAYLOAD_KEY = 'grape_jwt.payload'
9
9
 
10
+ def initialize(app, options = nil)
11
+ super(app, **(options || {}))
12
+ end
13
+
14
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
10
15
  def call(env)
11
16
  return app.call(env) if test_env?(env)
12
17
 
@@ -19,12 +24,18 @@ module SimpleJwtAuth
19
24
  logger.debug "Authorized request, JWT payload: #{payload}"
20
25
 
21
26
  app.call(env)
27
+ rescue SimpleJwtAuth::Errors::Forbidden => e
28
+ logger.warn "JWT issuer forbidden: #{e.message}"
29
+ rack_response(403, e.message)
30
+ rescue SimpleJwtAuth::Errors::IssuerError => e
31
+ logger.warn "JWT issuer error: #{e.message}"
32
+ rack_response(400, e.message)
22
33
  rescue JWT::DecodeError => e
23
34
  logger.warn "Unauthorized request, JWT error: #{e.message}"
24
-
25
- [401, { 'Content-Type' => 'application/json' }, [{ status: 401, error: e.message }.to_json]]
35
+ rack_response(401, e.message)
26
36
  end
27
37
  end
38
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
28
39
 
29
40
  private
30
41
 
@@ -32,6 +43,10 @@ module SimpleJwtAuth
32
43
  env['rack.test'] == true
33
44
  end
34
45
 
46
+ def rack_response(http_code, error_msg)
47
+ [http_code, { 'Content-Type' => 'application/json' }, [{ error: error_msg }.to_json]]
48
+ end
49
+
35
50
  def logger
36
51
  SimpleJwtAuth.configuration.logger
37
52
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SimpleJwtAuth
4
- VERSION = '0.0.1'
4
+ VERSION = '0.2.0'
5
5
  end
@@ -17,6 +17,7 @@ require_relative 'simple_jwt_auth/decode'
17
17
  # Middleware helpers
18
18
  require_relative 'simple_jwt_auth/middleware/faraday/jwt' if defined?(Faraday)
19
19
  require_relative 'simple_jwt_auth/middleware/grape/jwt' if defined?(Grape)
20
+ require_relative 'simple_jwt_auth/middleware/grape/authorisation' if defined?(Grape)
20
21
 
21
22
  module SimpleJwtAuth
22
23
  end
@@ -26,7 +26,7 @@ Gem::Specification.new do |spec|
26
26
  spec.bindir = 'exe'
27
27
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
28
  spec.require_paths = ['lib']
29
- spec.required_ruby_version = '>= 3.0.0'
29
+ spec.required_ruby_version = '>= 3.3.4'
30
30
 
31
31
  spec.add_dependency 'json'
32
32
  spec.add_dependency 'jwt'
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: moj-simple-jwt-auth
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jesus Laiz
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2023-02-14 00:00:00.000000000 Z
10
+ date: 2026-07-08 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: json
@@ -38,7 +37,6 @@ dependencies:
38
37
  - - ">="
39
38
  - !ruby/object:Gem::Version
40
39
  version: '0'
41
- description:
42
40
  email:
43
41
  - zheileman@users.noreply.github.com
44
42
  executables: []
@@ -62,6 +60,7 @@ files:
62
60
  - lib/simple_jwt_auth/encode.rb
63
61
  - lib/simple_jwt_auth/errors.rb
64
62
  - lib/simple_jwt_auth/middleware/faraday/jwt.rb
63
+ - lib/simple_jwt_auth/middleware/grape/authorisation.rb
65
64
  - lib/simple_jwt_auth/middleware/grape/jwt.rb
66
65
  - lib/simple_jwt_auth/secrets.rb
67
66
  - lib/simple_jwt_auth/traits/configurable.rb
@@ -73,7 +72,6 @@ licenses:
73
72
  - MIT
74
73
  metadata:
75
74
  rubygems_mfa_required: 'true'
76
- post_install_message:
77
75
  rdoc_options: []
78
76
  require_paths:
79
77
  - lib
@@ -81,15 +79,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
81
79
  requirements:
82
80
  - - ">="
83
81
  - !ruby/object:Gem::Version
84
- version: 3.0.0
82
+ version: 3.3.4
85
83
  required_rubygems_version: !ruby/object:Gem::Requirement
86
84
  requirements:
87
85
  - - ">="
88
86
  - !ruby/object:Gem::Version
89
87
  version: '0'
90
88
  requirements: []
91
- rubygems_version: 3.3.7
92
- signing_key:
89
+ rubygems_version: 3.6.2
93
90
  specification_version: 4
94
91
  summary: Simple JWT Auth ruby gem with middleware for Faraday and Grape.
95
92
  test_files: []