jwt_easy 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9e7c1abc2e2e5159abc61e45102226fe2b252f9b
4
+ data.tar.gz: 7c393cced4e3786d6b5834855716827d69890671
5
+ SHA512:
6
+ metadata.gz: 9159765198fcb834e2a316b54f1eed749118cf90d1dfe89f9dc7884b9267e12705e0d9090f997b551d14d6d9dcdae2a9ef1374c21d9ae835d5c8f7416f7792e6
7
+ data.tar.gz: 26dfb051ded825aa7d6df8bf4bb4758c60cceff754f7b5fe7588e1fb520688d9a2330181187bafda0b8be5eb582cf79e9ee24aff5149eee34249e55bd959f006
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.rubocop.yml ADDED
@@ -0,0 +1,13 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.4
3
+
4
+ Documentation:
5
+ Enabled: false
6
+
7
+ Metrics/BlockLength:
8
+ Exclude:
9
+ - 'spec/**/*'
10
+ - '*.gemspec'
11
+
12
+ Metrics/LineLength:
13
+ Max: 100
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.4.0
5
+ before_install: gem install bundler -v 1.13.7
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in jwt_easy.gemspec
6
+ gemspec
7
+
8
+ ruby '2.4.0'
data/README.md ADDED
@@ -0,0 +1,56 @@
1
+ # JWTEasy
2
+
3
+ JWTEasy is a simple wrapper for the [JWT](https://github.com/jwt/ruby-jwt) gem (version 1.x) that hopes to make generating and consuming various types of JSON web tokens a little easier.
4
+
5
+ > **Note:** Currently only supports plain, EXP and NBF tokens with HMAC HS256 encryption.
6
+
7
+ ## Usage
8
+
9
+ Generating a plain token without encryption might look something like:
10
+
11
+ ```ruby
12
+ token = JWTEasy.encode(id: 'some-identifying-information')
13
+ ```
14
+
15
+ You'd likely want to configure things before though:
16
+
17
+ ```ruby
18
+ # config/initializers/jwt_easy.rb
19
+ JWTEasy.configure do |config|
20
+ config.expiration_time = 3_600
21
+ config.secret = ENV['JWT_EASY_SECRET']
22
+ config.algorithm = JWTEasy::ALGORITHM_HMAC_HS256
23
+ end
24
+ ````
25
+
26
+ Of course you're able to consume tokens just as easily:
27
+
28
+ ```ruby
29
+ JWTEasy.decode(token).id #=> 'some-identifying-information'
30
+ ```
31
+
32
+ ## Installation
33
+
34
+ Add this line to your application's Gemfile:
35
+
36
+ ```ruby
37
+ gem 'jwt_easy'
38
+ ```
39
+
40
+ And then execute:
41
+
42
+ $ bundle
43
+
44
+ Or install it yourself as:
45
+
46
+ $ gem install jwt_easy
47
+
48
+ ## Development
49
+
50
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
51
+
52
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
53
+
54
+ ## Contributing
55
+
56
+ Bug reports and pull requests are welcome on GitHub at https://github.com/lshepstone/jwt_easy.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'jwt_easy'
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require 'irb'
15
+ IRB.start
data/bin/rspec ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rspec' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require 'pathname'
12
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ require 'rubygems'
16
+ require 'bundler/setup'
17
+
18
+ load Gem.bin_path('rspec-core', 'rspec')
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/jwt_easy.gemspec ADDED
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ lib = File.expand_path('../lib', __FILE__)
5
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
+ require 'jwt_easy/version'
7
+
8
+ Gem::Specification.new do |spec|
9
+ spec.name = 'jwt_easy'
10
+ spec.version = JWTEasy::VERSION
11
+ spec.authors = ['Lawrance Shepstone']
12
+ spec.email = ['lawrance.shepstone@gmail.com']
13
+
14
+ spec.summary = 'jwt_easy'
15
+ spec.description = 'Library for generating and consuming JSON web tokens easily.'
16
+ spec.homepage = 'https://github.com/lshepstone/jwt_easy'
17
+ spec.license = 'MIT'
18
+
19
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
20
+ f.match(%r{^(test|spec|features)/})
21
+ end
22
+ spec.bindir = 'exe'
23
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
+ spec.require_paths = ['lib']
25
+
26
+ spec.add_dependency 'jwt', '~> 1.5'
27
+
28
+ spec.add_development_dependency 'bundler', '~> 1.13'
29
+ spec.add_development_dependency 'rake', '~> 10.0'
30
+ spec.add_development_dependency 'rspec', '~> 3.0'
31
+ spec.add_development_dependency 'rubocop', '~> 0'
32
+ spec.add_development_dependency 'pry', '~> 0'
33
+ spec.add_development_dependency 'timecop', '~> 0'
34
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JWTEasy
4
+ # A configuration object used to define various options for encoding and decoding tokens.
5
+ #
6
+ # * This is usually not instantiated directly, but rather by way of calling
7
+ # +JWTEasy.configure+.
8
+ class Configuration
9
+ attr_writer :algorithm
10
+
11
+ attr_accessor :secret,
12
+ :expiration_time,
13
+ :not_before_time
14
+
15
+ # Gets the algorithm to use when encoding tokens
16
+ #
17
+ # * If no secret has been set, this returns 'none'
18
+ #
19
+ # @return [String] the algorithm to be used
20
+ def algorithm
21
+ secret ? (@algorithm || ALGORITHM_HMAC_HS256) : 'none'
22
+ end
23
+
24
+ # Infers the claim to observe during encoding or decoding.
25
+ #
26
+ # @return [Symbol] short name for the identified claim
27
+ def claim
28
+ if expiration_time
29
+ CLAIM_EXPIRATION_TIME
30
+ elsif not_before_time
31
+ CLAIM_NOT_BEFORE_TIME
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JWTEasy
4
+ # Short-names for various supported claim types.
5
+ #
6
+ CLAIM_EXPIRATION_TIME = :exp
7
+ CLAIM_NOT_BEFORE_TIME = :nbf
8
+
9
+ # Algorithm identifiers for supported algorithms.
10
+ #
11
+ ALGORITHM_HMAC_HS256 = 'HS256'
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Hash
4
+ def except(*keys)
5
+ dup.except!(*keys)
6
+ end
7
+
8
+ def except!(*keys)
9
+ keys.each { |key| delete(key) }
10
+ self
11
+ end
12
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JWTEasy
4
+ # Decoder object for decoding tokens.
5
+ #
6
+ # * This is usually not instantiated directly, but rather by way of
7
+ # calling +JWTEasy.decode+.
8
+ class Decoder
9
+ attr_reader :token,
10
+ :configuration
11
+
12
+ # Initializes a new encoder instance.
13
+ #
14
+ # * If no configuration object is passed or is +nil+, the value of
15
+ # +JWTEasy.configuration+ is used as the configuration object
16
+ #
17
+ # @param [String] token the token to be decoded
18
+ # @param [Configuration] configuration the configuration object
19
+ def initialize(token, configuration = nil)
20
+ @token = token
21
+ @configuration = configuration || JWTEasy.configuration
22
+ @headers = {}
23
+ end
24
+
25
+ # Decodes the token with the configured options.
26
+ #
27
+ # @return [Result] the result of the decoding
28
+ def decode
29
+ Result.new(*JWT.decode(token, configuration.secret, verification?, headers))
30
+ end
31
+
32
+ # Determines if verification will be used during decoding.
33
+ #
34
+ # @return [Boolean] if verification will be used or not
35
+ def verification?
36
+ configuration.secret.nil? == false
37
+ end
38
+
39
+ # Determines the headers to be used during decoding.
40
+ #
41
+ # @return [Hash] the headers to be used
42
+ def headers
43
+ @headers.tap do |headers|
44
+ headers[:algorithm] = configuration.algorithm if verification?
45
+
46
+ case configuration.claim
47
+ when CLAIM_EXPIRATION_TIME
48
+ headers[:validate_exp] = true
49
+ when CLAIM_NOT_BEFORE_TIME
50
+ headers[:validate_nbf] = true
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JWTEasy
4
+ # Encoder object for generating new tokens.
5
+ #
6
+ # * This is usually not instantiated directly, but rather by way of
7
+ # calling +JWTEasy.encode+.
8
+ class Encoder
9
+ attr_reader :data,
10
+ :configuration
11
+
12
+ # Initializes a new encoder instance.
13
+ #
14
+ # * If no configuration object is passed or is +nil+, the value of
15
+ # +JWTEasy.configuration+ is used as the configuration object
16
+ #
17
+ # @param [Object] data the data to be encoded
18
+ # @param [Configuration] configuration the configuration object
19
+ def initialize(data, configuration = nil)
20
+ @data = data
21
+ @configuration = configuration || JWTEasy.configuration
22
+ end
23
+
24
+ # Encodes the data with the configured options.
25
+ #
26
+ # @return [String] the encoded token
27
+ def encode
28
+ JWT.encode(payload, configuration.secret, configuration.algorithm)
29
+ end
30
+
31
+ # Determines the structure of the payload to be encoded.
32
+ #
33
+ # @return [Object] the payload to be encoded
34
+ def payload
35
+ case configuration.claim
36
+ when CLAIM_EXPIRATION_TIME
37
+ { data: data, exp: expiration_time }
38
+ when CLAIM_NOT_BEFORE_TIME
39
+ { data: data, nbf: not_before_time }
40
+ else
41
+ data
42
+ end
43
+ end
44
+
45
+ # Calculates the expiration time if configured.
46
+ #
47
+ # @return [Integer] the expiration time
48
+ def expiration_time
49
+ Time.now.to_i + configuration.expiration_time
50
+ end
51
+
52
+ # Calculates the not before time if configured.
53
+ #
54
+ # @return [Integer] the not before time
55
+ def not_before_time
56
+ Time.now.to_i - configuration.not_before_time
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JWTEasy
4
+ # Result object that represents a decoded token.
5
+ #
6
+ # * This is usually not instantiated directly, but rather by way of
7
+ # calling +JWTEasy.encode+.
8
+ class Result
9
+ CLAIM_KEYS = [
10
+ CLAIM_EXPIRATION_TIME,
11
+ CLAIM_NOT_BEFORE_TIME
12
+ ].freeze
13
+
14
+ attr_reader :payload,
15
+ :headers
16
+
17
+ # Initializes a new result instance.
18
+ #
19
+ # @param [Object] payload from decoding a token
20
+ # @param [Hash] headers from decoding a token
21
+ def initialize(payload = nil, headers = nil)
22
+ @payload = payload
23
+ @headers = headers
24
+ end
25
+
26
+ # Determines the encoded data from the payload structure.
27
+ #
28
+ # * If the payload is a hash that contains a claim key alongside other data
29
+ # attributes, only a hash with the data attributes will be returned.
30
+ #
31
+ # * If the payload is hash that contains data in a data attribute alongside
32
+ # any claim keys, the value of the data attribute is returned.
33
+ #
34
+ # * If the payload is anything but a hash, the payload is returned.
35
+ #
36
+ # @return [Object] the data encoded with the payload
37
+ def data
38
+ @data ||= if payload.is_a?(Hash)
39
+ if claim && payload.key?('data')
40
+ payload['data']
41
+ else
42
+ payload.except(*CLAIM_KEYS.map(&:to_s))
43
+ end
44
+ else
45
+ payload
46
+ end
47
+ end
48
+
49
+ # Infers the claim that was observed during decoding.
50
+ #
51
+ # @return [Symbol] short name for the identified claim
52
+ def claim
53
+ @claim ||= CLAIM_KEYS.find { |claim| payload&.key?(claim.to_s) }
54
+ end
55
+
56
+ def method_missing(method, *arguments, &block)
57
+ data.is_a?(Hash) && data.key?(method.to_s) ? data[method.to_s] : super
58
+ end
59
+
60
+ def respond_to_missing?(method, _include_private = false)
61
+ data.is_a?(Hash) && data.key?(method.to_s) || super
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JWTEasy
4
+ VERSION = '0.1.0'
5
+ end
data/lib/jwt_easy.rb ADDED
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jwt'
4
+ require 'jwt_easy/core_ext/hash'
5
+ require 'jwt_easy/constants'
6
+ require 'jwt_easy/encoder'
7
+ require 'jwt_easy/configuration'
8
+ require 'jwt_easy/result'
9
+ require 'jwt_easy/decoder'
10
+ require 'jwt_easy/version'
11
+
12
+ # JWTEasy is a simple wrapper for the JWT gem that hopes to make generating and consuming various
13
+ # types of JSON web tokens a little easier.
14
+ #
15
+ # == Usage
16
+ #
17
+ # Generating a plain token without encryption might look something like:
18
+ #
19
+ # token = JWTEasy.encode(id: 'some-identifying-information')
20
+ #
21
+ # You'd likely want to configure things before though:
22
+ #
23
+ # # config/initializers/jwt_easy.rb
24
+ # JWTEasy.configure do |config|
25
+ # config.not_before_time = 3_600
26
+ # config.secret = ENV['JWT_EASY_SECRET']
27
+ # config.algorithm = JWTEasy::ALGORITHM_HMAC_HS256
28
+ # end
29
+ #
30
+ # Of course you're able to consume tokens just as easily:
31
+ #
32
+ # JWTEasy.decode(token).id #=> 'some-identifying-information'
33
+ #
34
+ # @see JWTEasy.encode
35
+ # @see JWTEasy.decode
36
+ # @see JWTEasy.configure
37
+ module JWTEasy
38
+ module_function
39
+
40
+ # Gets the configuration object.
41
+ #
42
+ # If none was set, a new configuration object is instantiated and returned.
43
+ #
44
+ # @return [Configuration] the configuration object
45
+ #
46
+ # @see Configuration
47
+ def configuration
48
+ @configuration ||= Configuration.new
49
+ end
50
+
51
+ # Allows for configuring the library using a block.
52
+ #
53
+ # @example Configuration using a block
54
+ # JWTEasy.configure do |config|
55
+ # # ...
56
+ # end
57
+ #
58
+ # @see Configuration
59
+ def configure
60
+ yield(configuration) if block_given?
61
+ end
62
+
63
+ # Instantiates a new encoder and encodes the provided data and the global configuration object.
64
+ #
65
+ # @example Generate a token from some data
66
+ # JWTEasy.encode(id: 'some-identifying-information')
67
+ #
68
+ # @param [Object] data the data to be encoded in the token
69
+ #
70
+ # @return [String] JSON web token
71
+ #
72
+ # @see Encoder
73
+ def encode(data)
74
+ Encoder.new(data, configuration).encode
75
+ end
76
+
77
+ # Instantiates a new decoder with the provided data and the global configuration object.
78
+ #
79
+ # @example Decode a token
80
+ # JWTEasy.decode(token)
81
+ #
82
+ # @param [String] token the token to be decoded
83
+ #
84
+ # @return [Result] Result of the decode
85
+ #
86
+ # @see Encoder
87
+ def decode(token)
88
+ Decoder.new(token, configuration).decode
89
+ end
90
+ end
metadata ADDED
@@ -0,0 +1,161 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jwt_easy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Lawrance Shepstone
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-09-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: jwt
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.13'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.13'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: timecop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: Library for generating and consuming JSON web tokens easily.
112
+ email:
113
+ - lawrance.shepstone@gmail.com
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - ".gitignore"
119
+ - ".rspec"
120
+ - ".rubocop.yml"
121
+ - ".travis.yml"
122
+ - Gemfile
123
+ - README.md
124
+ - Rakefile
125
+ - bin/console
126
+ - bin/rspec
127
+ - bin/setup
128
+ - jwt_easy.gemspec
129
+ - lib/jwt_easy.rb
130
+ - lib/jwt_easy/configuration.rb
131
+ - lib/jwt_easy/constants.rb
132
+ - lib/jwt_easy/core_ext/hash.rb
133
+ - lib/jwt_easy/decoder.rb
134
+ - lib/jwt_easy/encoder.rb
135
+ - lib/jwt_easy/result.rb
136
+ - lib/jwt_easy/version.rb
137
+ homepage: https://github.com/lshepstone/jwt_easy
138
+ licenses:
139
+ - MIT
140
+ metadata: {}
141
+ post_install_message:
142
+ rdoc_options: []
143
+ require_paths:
144
+ - lib
145
+ required_ruby_version: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - ">="
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ required_rubygems_version: !ruby/object:Gem::Requirement
151
+ requirements:
152
+ - - ">="
153
+ - !ruby/object:Gem::Version
154
+ version: '0'
155
+ requirements: []
156
+ rubyforge_project:
157
+ rubygems_version: 2.6.8
158
+ signing_key:
159
+ specification_version: 4
160
+ summary: jwt_easy
161
+ test_files: []