has_jwt_token 0.2.1 → 0.2.2

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: 445d49f22461e8ad189d361639f786cea6723f1e7126a8510e0089879e6c9272
4
- data.tar.gz: '03580907964370e9611b4aff79526bf2f0ef2aa59e4c8728d8770d3e4448af45'
3
+ metadata.gz: 2ad68b66dda0ed71107ef9ee9437ab28c22ac3a67fd1748a93c16ccf5bc3441e
4
+ data.tar.gz: 638f7aafcad887e610ee30db1146c41ebe7d436444a2a34aa87985beee99adc0
5
5
  SHA512:
6
- metadata.gz: a6d5ab98751e620b5f0f46b4283e127a9e7151e4d615d60bb194186d28cf24a36c426fe0612df17d7d40eee26f30e0a53904034694003d5184a83a669e5d67d7
7
- data.tar.gz: d2d841bdb59c585d0bd52aa90b94b6d69d64ac309a1753431c954172b0996455290cef3411d2811ea59216a3184cea9de736d5eb92ad95fdec109b2696428b0d
6
+ metadata.gz: ccc67e129726ec0e7c5b78a46db992051b55d37c405f366cdf6477d333f685dedf5599288561fc30d5ee6bb4d29a7cbe714169544ef268635cc7c21d148ef868
7
+ data.tar.gz: '08efd1b82ccdf00f5459c02a64e845e2eba02bb1b582b2a5c3abe8f13769c0dc53f82e4b9ecdd9208daac06bc13d49bfd10023e313996afc2615056296b81f8b'
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- has_jwt_token (0.2.1)
4
+ has_jwt_token (0.2.2)
5
5
  bcrypt
6
6
  jwt
7
7
  rails (>= 5.0, < 7.0)
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  HasJwtToken provides JWT authetication for models which are kean to use `has_secure_password` in Rails app and wants to use it to grant jwt tokens.
4
4
 
5
- This gem is build on top of [Ruby's JWT](https://github.com/jwt/ruby-jwt) gem and it implements `JWT.encode` and `JWT.decode` methods.
5
+ This gem is build on top of [Ruby's JWT](https://github.com/jwt/ruby-jwt) gem and it implements `JWT.encode` and `JWT.decode` (with validation enabled) methods.
6
6
 
7
7
  ## Installation
8
8
 
@@ -53,7 +53,7 @@ end
53
53
  user = User.last
54
54
 
55
55
  user.authenicate(password) # => user with @token
56
- user.auhtenticate_with_jwt(token) # => user with @token
56
+ User.find_with_jwt(token) # => user with @token
57
57
  ```
58
58
 
59
59
  ## Roadmap
@@ -2,4 +2,5 @@
2
2
 
3
3
  require 'active_support/core_ext/module/delegation'
4
4
  require 'has_jwt_token/version'
5
+ require 'has_jwt_token/errors'
5
6
  require 'has_jwt_token/model'
@@ -1,22 +1,63 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Authenticatable
4
- def authenticate(password)
5
- super(password).tap do |authenticated|
6
- @token = authenticated && encode || nil
3
+ require 'has_jwt_token/jwt_proxy'
4
+
5
+ module HasJwtToken
6
+ module Authenticatable
7
+ module ClassMethods
8
+ def find_with_jwt(jwt_token)
9
+ payload = decode!(jwt_token)
10
+ find_by(authenticate_by => payload[authenticate_by])
11
+ &.tap { |model| model.token = model.encode }
12
+ rescue JWT::DecodeError
13
+ raise HasJwtToken::InvalidToken, 'Invalid token has been provided.'
14
+ end
15
+
16
+ private
17
+
18
+ def authenticate_by
19
+ @authenticate_by ||= begin
20
+ auth_by_attr = has_jwt_token.authenticate_by.to_s
21
+ return auth_by_attr if column_names.include?(auth_by_attr)
22
+
23
+ raise HasJwtToken::BadConfiguration, "#{auth_by_attr.inspect} must be one of model attributes."
24
+ end
25
+ end
26
+
27
+ def decode!(token)
28
+ HasJwtToken::JwtProxy.decode!(
29
+ token: token,
30
+ algorithm: has_jwt_token.algorithm,
31
+ secret: has_jwt_token.secret
32
+ )
33
+ end
7
34
  end
8
- end
9
35
 
10
- def authenticate_with_jwt(jwt_token)
11
- authenticated = decode!(jwt_token)
36
+ def self.included(base)
37
+ base.extend(ClassMethods)
38
+ end
39
+
40
+ def authenticate(password)
41
+ super(password).tap do |authenticated|
42
+ @token = authenticated && encode || nil
43
+ end
44
+ end
45
+
46
+ def encode
47
+ HasJwtToken::JwtProxy.encode(
48
+ algorithm: algorithm,
49
+ payload: model_payload.merge(claims_payload),
50
+ secret: secret,
51
+ header_fields: header_fields
52
+ )
53
+ end
54
+
55
+ private
56
+
57
+ delegate :algorithm, :secret, :model_payload, :claims_payload, :header_fields, to: :has_jwt_token
12
58
 
13
- if authenticated
14
- @token = encode
15
- self
16
- else
17
- @token = nil
59
+ def has_jwt_token
60
+ @has_jwt_token ||= self.class.has_jwt_token(self)
18
61
  end
19
- rescue JWT::DecodeError
20
- nil
21
62
  end
22
63
  end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HasJwtToken
4
+ HasJwtTokenError = Class.new(StandardError)
5
+
6
+ class InvalidToken < HasJwtTokenError; end
7
+ class BadConfiguration < HasJwtTokenError; end
8
+ end
@@ -7,9 +7,7 @@ module HasJwtToken
7
7
  def has_jwt_token(model = nil)
8
8
  @has_jwt_token ||= JwtConfiguration.new
9
9
  yield(@has_jwt_token) if block_given?
10
- @has_jwt_token.tap do |config|
11
- config.model = model if model
12
- end
10
+ @has_jwt_token.tap { |jwt| jwt.model = model if model }
13
11
  end
14
12
  end
15
13
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  module HasJwtToken
4
4
  class JwtConfiguration
5
+ DEFAULT_AUTH_ATTRIBUTE = :id
5
6
  CLAIMS = {
6
7
  expiration_time: :exp,
7
8
  not_before_time: :nbf,
@@ -57,7 +58,8 @@ module HasJwtToken
57
58
  end
58
59
  end
59
60
 
60
- def payload(name = nil, value = nil)
61
+ def payload(name = nil, value: nil, auth_by: false)
62
+ @authenticate_by = name if auth_by
61
63
  @payload[name] = value || ->(model) { model.respond_to?(name) && model.public_send(name) } if name
62
64
  end
63
65
 
@@ -77,5 +79,9 @@ module HasJwtToken
77
79
  val.is_a?(Proc) ? val.call : val
78
80
  end
79
81
  end
82
+
83
+ def authenticate_by
84
+ @authenticate_by || DEFAULT_AUTH_ATTRIBUTE
85
+ end
80
86
  end
81
87
  end
@@ -4,31 +4,14 @@ require 'jwt'
4
4
 
5
5
  module HasJwtToken
6
6
  class JwtProxy
7
- attr_reader :algorithm, :payload, :secret, :header_fields
7
+ class << self
8
+ def encode(payload:, secret: '', algorithm: '', header_fields: {})
9
+ JWT.encode(payload, secret, algorithm, header_fields)
10
+ end
8
11
 
9
- def initialize(algorithm: '', payload: {}, secret: '', header_fields: {})
10
- @algorithm = algorithm
11
- @payload = payload
12
- @secret = secret
13
- @header_fields = header_fields
14
- end
15
-
16
- def encode
17
- JWT.encode(payload, secret, algorithm, header_fields)
18
- end
19
-
20
- def decode(token)
21
- JWT.decode(token, secret, false, algorithm: algorithm)[0]
22
- end
23
-
24
- def decode!(token)
25
- JWT.decode(token, secret, true, algorithm: algorithm)[0]
26
- end
27
-
28
- def valid?(token)
29
- decode!(token) && true
30
- rescue JWT::DecodeError
31
- false
12
+ def decode!(token:, secret: '', algorithm: '')
13
+ JWT.decode(token, secret, true, algorithm: algorithm)[0]
14
+ end
32
15
  end
33
16
  end
34
17
  end
@@ -4,18 +4,16 @@ require 'active_model'
4
4
  require 'bcrypt'
5
5
  require 'has_jwt_token/authenticatable'
6
6
  require 'has_jwt_token/has_jwt_model_configuration'
7
- require 'has_jwt_token/jwt_tokenable'
8
7
 
9
8
  module HasJwtToken
10
9
  module Model
11
- attr_reader :token
10
+ attr_accessor :token
12
11
 
13
12
  def self.included(base)
14
13
  base.include(ActiveModel::SecurePassword)
15
14
  base.has_secure_password
16
15
  base.include(Authenticatable)
17
16
  base.extend(HasJwtModelConfiguration)
18
- base.include(JwtTokenable)
19
17
  end
20
18
  end
21
19
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module HasJwtToken
4
- VERSION = '0.2.1'
4
+ VERSION = '0.2.2'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: has_jwt_token
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jokūbas Pučinskas
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-11-06 00:00:00.000000000 Z
11
+ date: 2021-01-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bcrypt
@@ -167,10 +167,10 @@ files:
167
167
  - has_jwt_token.gemspec
168
168
  - lib/has_jwt_token.rb
169
169
  - lib/has_jwt_token/authenticatable.rb
170
+ - lib/has_jwt_token/errors.rb
170
171
  - lib/has_jwt_token/has_jwt_model_configuration.rb
171
172
  - lib/has_jwt_token/jwt_configuration.rb
172
173
  - lib/has_jwt_token/jwt_proxy.rb
173
- - lib/has_jwt_token/jwt_tokenable.rb
174
174
  - lib/has_jwt_token/model.rb
175
175
  - lib/has_jwt_token/version.rb
176
176
  homepage: https://github.com/pucinsk/has_jwt_token
@@ -1,44 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'has_jwt_token/jwt_proxy'
4
-
5
- module HasJwtToken
6
- module JwtTokenable
7
- delegate :algorithm, :secret, :claims_payload, :header_fields, to: :has_jwt_token
8
-
9
- def encode
10
- with_jwt_configuration(&:encode)
11
- end
12
-
13
- def decode(token)
14
- with_jwt_configuration { |jwt| jwt.decode(token) }
15
- end
16
-
17
- def decode!(token)
18
- with_jwt_configuration { |jwt| jwt.decode!(token) }
19
- end
20
-
21
- def has_jwt_token
22
- self.class.has_jwt_token(self)
23
- end
24
-
25
- private
26
-
27
- def payload
28
- @payload ||= has_jwt_token.model_payload.merge(claims_payload)
29
- end
30
-
31
- def with_jwt_configuration
32
- yield(jwt_proxy)
33
- end
34
-
35
- def jwt_proxy
36
- @jwt_proxy ||= JwtProxy.new(
37
- algorithm: algorithm,
38
- payload: payload,
39
- secret: secret,
40
- header_fields: header_fields
41
- )
42
- end
43
- end
44
- end