bs_jwt 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: fd45222b4a9bdddb2f839cc91d7de23275fdaacbf7535f3e9b0d5a2a1cc29bf6
4
+ data.tar.gz: f15546b20ca37c595fe2bd0ffbc7a2a958b2348a716f74bd5e8fe17cd4a354d3
5
+ SHA512:
6
+ metadata.gz: 701309fd19d4aa51851382198d30c7e1ca24d2e84ff13e1b5e034971ee18d1a90458abbbdb9f76d60a183252766d042220f0ce6eebef89874e3cfe60dae1ebb9
7
+ data.tar.gz: 1a7abc5763cd6d03b1e4dda287e6c241556c8ed74db31732c61bc810c59e22191c2a2b9e2a95c6049a1021bbacb23795bed9864b3631e212b0a7bdb4ca01fb7f
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
data/.gitlab-ci.yml ADDED
@@ -0,0 +1,25 @@
1
+ image: "ruby:2.5"
2
+
3
+ before_script:
4
+ - ruby -v
5
+ - gem install bundler --no-ri --no-rdoc # Bundler is not installed with the image
6
+
7
+ rubocop:
8
+ stage: test
9
+ script:
10
+ - bundle install -j $(nproc) --path vendor # Install dependencies into ./vendor/ruby
11
+ - bundle exec rubocop
12
+
13
+ rspec:
14
+ stage: test
15
+ script:
16
+ - bundle install -j $(nproc) --path vendor # Install dependencies into ./vendor/ruby
17
+ - bundle exec rspec spec
18
+
19
+ publish_gem:
20
+ stage: deploy
21
+ only:
22
+ - master
23
+ when: manual
24
+ script:
25
+ - 'bin/build_and_publish'
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,42 @@
1
+ # This is the configuration used to check the rubocop source code.
2
+
3
+ AllCops:
4
+ TargetRubyVersion: 2.5
5
+ Exclude:
6
+ - 'vendor/**/*'
7
+ - 'spec/fixtures/**/*'
8
+
9
+ Lint/HandleExceptions:
10
+ Exclude:
11
+ - 'bin/rails'
12
+ - 'bin/rake'
13
+ - 'bin/rspec'
14
+
15
+ Style/Encoding:
16
+ Enabled: true
17
+
18
+ Style/NumericLiterals:
19
+ Enabled: false
20
+
21
+ Style/RescueModifier:
22
+ Enabled: false
23
+
24
+ # false error when run with Neomake
25
+ Naming/FileName:
26
+ Enabled: false
27
+
28
+ Metrics/LineLength:
29
+ Max: 120
30
+
31
+ Style/RescueStandardError:
32
+ Enabled: false
33
+
34
+ Style/Documentation:
35
+ Enabled: false
36
+
37
+ Metrics/BlockLength:
38
+ Exclude:
39
+ - '**/*.rake'
40
+ - 'spec/**/*.rb'
41
+ - 'config/**/*.rb'
42
+ - '*.gemspec'
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-2.5.1
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.5.1
5
+ before_install: gem install bundler -v 1.16.1
data/CHANGELOG.md ADDED
@@ -0,0 +1,72 @@
1
+ # Change Log
2
+ All notable changes to this project will be documented in this file.
3
+ This project adheres to [Semantic Versioning](http://semver.org/).
4
+ ## Unreleased
5
+ ## [2.0.1] - 2018-07-23
6
+ No changes. Version 2.0.0 was accidentally deleted from ruby gems.
7
+
8
+ ## [2.0.0] - 2018-07-13
9
+ ### Removed
10
+ - Remove Authentication#buddy_id
11
+
12
+ ## [1.2.0] - 2018-07-10
13
+ ### Added
14
+ - Add issued_at to the authentication model
15
+
16
+ ## [1.1.0] - 2018-07-09
17
+ ### Added
18
+ - Authentication#to_h returns the instance attributes as hash.
19
+
20
+ ### Changed
21
+ - Authentication.new now accepts an attribute hash.
22
+
23
+ ## [1.0.3] - 2018-07-02
24
+ ### Changed
25
+ - Rename factory authentication to bs_jwt_authentication.
26
+
27
+ ## [1.0.2] - 2018-06-26
28
+ ### Changed
29
+ - Set email and display_name in the authentication factory for better testing support.
30
+
31
+ ## [1.0.1] - 2018-06-22
32
+ ### Added
33
+ - `BsJwt.verify_and_decode/1` and `BsJwt.verify_and_decode_auth0_hash`, which basically do
34
+ the same as the bang version, but instead of raising exceptions, they return `nil`.
35
+
36
+ ## [1.0.0] - 2018-06-22
37
+ ### Added
38
+ - `Authentication` class, which is now returned by the `BsJwt.verify_and_decode!/1` and
39
+ `BsJwt.verify_and_decode_auth0_hash!/1` (formerly `process_auth0_hash/1`) in place of
40
+ a payload Hash.
41
+
42
+ ### Changed
43
+ - `BsJwt.process_auth0_hash/1` has been renamed to `BsJwt.verify_and_decode_auth0_hash!/1`
44
+ - `BsJwt.process_jwt/1` has been renamed to `BsJwt.verify_and_decode!/1`
45
+ Due to the change in public method names, major version has been bumped to 1.
46
+
47
+ ## Unreleased
48
+ ### Added
49
+ - First version of this gem.
50
+ -----------------------------------------------------------------------------------------
51
+
52
+ Template:
53
+ ## [0.0.0] - 2014-05-31
54
+ ### Added
55
+ - something was added
56
+
57
+ ### Changed
58
+ - something changed
59
+
60
+ ### Deprecated
61
+ - something is deprecated
62
+
63
+ ### Removed
64
+ - something was removed
65
+
66
+ ### Fixed
67
+ - something was fixed
68
+
69
+ ### Security
70
+ - a security fix
71
+
72
+ Following "[Keep a CHANGELOG](http://keepachangelog.com/)"
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
+
7
+ # Specify your gem's dependencies in bs-jwt.gemspec
8
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,102 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ bs_jwt (2.0.1)
5
+ activesupport (>= 4.0)
6
+ faraday (>= 0.8)
7
+ json-jwt (~> 1.9.4)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ activesupport (5.2.0)
13
+ concurrent-ruby (~> 1.0, >= 1.0.2)
14
+ i18n (>= 0.7, < 2)
15
+ minitest (~> 5.1)
16
+ tzinfo (~> 1.1)
17
+ addressable (2.5.2)
18
+ public_suffix (>= 2.0.2, < 4.0)
19
+ aes_key_wrap (1.0.1)
20
+ ast (2.4.0)
21
+ bindata (2.4.3)
22
+ byebug (10.0.2)
23
+ coderay (1.1.2)
24
+ concurrent-ruby (1.0.5)
25
+ crack (0.4.3)
26
+ safe_yaml (~> 1.0.0)
27
+ diff-lcs (1.3)
28
+ factory_bot (4.10.0)
29
+ activesupport (>= 3.0.0)
30
+ faraday (0.15.2)
31
+ multipart-post (>= 1.2, < 3)
32
+ hashdiff (0.3.7)
33
+ i18n (1.0.1)
34
+ concurrent-ruby (~> 1.0)
35
+ jaro_winkler (1.5.1)
36
+ json-jwt (1.9.4)
37
+ activesupport
38
+ aes_key_wrap
39
+ bindata
40
+ method_source (0.9.0)
41
+ minitest (5.11.3)
42
+ multipart-post (2.0.0)
43
+ parallel (1.12.1)
44
+ parser (2.5.1.0)
45
+ ast (~> 2.4.0)
46
+ powerpack (0.1.2)
47
+ pry (0.11.3)
48
+ coderay (~> 1.1.0)
49
+ method_source (~> 0.9.0)
50
+ pry-byebug (3.6.0)
51
+ byebug (~> 10.0)
52
+ pry (~> 0.10)
53
+ public_suffix (3.0.2)
54
+ rainbow (3.0.0)
55
+ rake (10.5.0)
56
+ rspec (3.7.0)
57
+ rspec-core (~> 3.7.0)
58
+ rspec-expectations (~> 3.7.0)
59
+ rspec-mocks (~> 3.7.0)
60
+ rspec-core (3.7.1)
61
+ rspec-support (~> 3.7.0)
62
+ rspec-expectations (3.7.0)
63
+ diff-lcs (>= 1.2.0, < 2.0)
64
+ rspec-support (~> 3.7.0)
65
+ rspec-mocks (3.7.0)
66
+ diff-lcs (>= 1.2.0, < 2.0)
67
+ rspec-support (~> 3.7.0)
68
+ rspec-support (3.7.1)
69
+ rubocop (0.57.2)
70
+ jaro_winkler (~> 1.5.1)
71
+ parallel (~> 1.10)
72
+ parser (>= 2.5)
73
+ powerpack (~> 0.1)
74
+ rainbow (>= 2.2.2, < 4.0)
75
+ ruby-progressbar (~> 1.7)
76
+ unicode-display_width (~> 1.0, >= 1.0.1)
77
+ ruby-progressbar (1.9.0)
78
+ safe_yaml (1.0.4)
79
+ thread_safe (0.3.6)
80
+ tzinfo (1.2.5)
81
+ thread_safe (~> 0.1)
82
+ unicode-display_width (1.4.0)
83
+ webmock (3.4.2)
84
+ addressable (>= 2.3.6)
85
+ crack (>= 0.3.2)
86
+ hashdiff
87
+
88
+ PLATFORMS
89
+ ruby
90
+
91
+ DEPENDENCIES
92
+ bs_jwt!
93
+ bundler (~> 1.16)
94
+ factory_bot
95
+ pry-byebug
96
+ rake (~> 10.0)
97
+ rspec (~> 3.0)
98
+ rubocop (= 0.57.2)
99
+ webmock
100
+
101
+ BUNDLED WITH
102
+ 1.16.2
data/LICENSE ADDED
@@ -0,0 +1,11 @@
1
+ Copyright 2018 Karol Moroz <k.j.moroz@gmail.com>
2
+
3
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
4
+
5
+ 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
6
+
7
+ 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8
+
9
+ 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
10
+
11
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,69 @@
1
+ # BS::JWT
2
+
3
+ Simple library for verifying Auth0 JWTs
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'bs-jwt'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install bs-jwt
20
+
21
+ ## Usage
22
+
23
+ Set the auth0 domain (in an initializer).
24
+
25
+ ```ruby
26
+ BsJwt.auth0_domain = ENV.fetch('AUTH0_DOMAIN', 'reverse-retail.eu.auth0.com')
27
+ ```
28
+
29
+ Decode a JWT token:
30
+
31
+ ```ruby
32
+ jwt_token =
33
+ 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik5FTTNNRFZGTlRZME5VTkRRVEpEUWtFeE5rRkJSamhET0RBMlF6Y3hOemd4TkRrNU1FRXh' \
34
+ 'SUSJ9.eyJodHRwczovL2J1ZGR5LmJ1ZGR5YW5kc2VsbHkuY29tL2J1ZGR5X2lkIjozMzcsImh0dHBzOi8vYnVkZHkuYnVkZHlhbmRzZWxseS5jb20vc' \
35
+ 'm9sZXMiOlsiYWRtaW4iXSwibmlja25hbWUiOiJKYW5uaWsgR3JhdyIsIm5hbWUiOiJqLmdyYXdAYnVkZHlhbmRzZWxseS5jb20iLCJ1cGRhdGVkX2F0' \
36
+ 'IjoiMjAxOC0wNi0yMlQwOToxMDoyNS45NDhaIiwiaXNzIjoiaHR0cHM6Ly9yZXZlcnNlLXJldGFpbC5ldS5hdXRoMC5jb20vIiwic3ViIjoiYXV0aDB' \
37
+ '8NGUzYTJmZWY3MWI1NzE5NjFjMWIyMjkiLCJhdWQiOiJDdE9kbDVkMERVNE9HMWJEdEZmT3ZWbFVoN0YxODlHMiIsImlhdCI6MTUyOTY1ODYyOSwiZX' \
38
+ 'hwIjoxNTI5Njk0NjI5fQ.omtjxv_4OJ1gG3RnfsBRn7jBY1oLExYcOrKKIrDIBKdtYoBtzbNZuLfXi2rfEnBMEd3f-MNPU9Ynot6VF6Ps16-V_LHGWb' \
39
+ 'jr4trkt2ACrXUKcg7cc3hxiMVauj2ehoofzsWXY78BGCZKXFWyUidnLcLBgY2yhAhTds5eWQpi7MOpDVTQqIcXuRpidS499myZnw0hueyztuM9yUhuN' \
40
+ 'E6l_ygqEglgQ8qr0p6ljiZvQ1lq6w_alOvzyfqRP4a5ClKM7LzlnP5DCsUJN1qJdoPhJNYyjxu7H-1qxJtJaaBoD74-dX3-bYkinSRqfro19tD0FSON' \
41
+ 'TOfdwWc1XPgJ-6bDzQ'
42
+ BsJwt.verify_and_decode!(jwt_token)
43
+ ```
44
+
45
+ Decode a JWT token directly from the omniauth hash:
46
+
47
+ ```ruby
48
+ BsJwt.verify_and_decode_auth0_hash!(request.env['omniauth.auth'])
49
+ ```
50
+
51
+ ## Testing support
52
+
53
+ Some `factory_bot` factories are included in this gem. To use them add
54
+
55
+ ```ruby
56
+ require 'bs_jwt/factories'
57
+ ```
58
+
59
+ before requiring `factory_bot` to your spec_helper.
60
+
61
+ ## Publish new gem version
62
+
63
+ 1) Set the new version in the [version file](lib/bs_jwt/version.rb).
64
+
65
+ 2) Update the [changelog](CHANGELOG.md)
66
+
67
+ 3) Make a bump version commit and push it
68
+
69
+ 4) Visit https://gitlab.com/ReverseRetail/bs_jwt/pipelines. Wait for the tests to pass and trigger the publish_gem job.
data/Rakefile ADDED
@@ -0,0 +1,16 @@
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
9
+
10
+ begin
11
+ require 'rubocop/rake_task'
12
+ RuboCop::RakeTask.new
13
+ task default: :rubocop
14
+ rescue LoadError => e
15
+ puts "rubocop not loaded (#{e.class.name})"
16
+ end
@@ -0,0 +1,10 @@
1
+ #!/bin/bash
2
+
3
+ set -o errexit
4
+ set -o nounset
5
+
6
+ gem build bs_jwt.gemspec
7
+ echo "---" > ~/.gem/credentials
8
+ echo ":rubygems_api_key: $RUBY_GEMS_API_TOKEN" >> ~/.gem/credentials
9
+ chmod 0600 ~/.gem/credentials
10
+ gem push "$(find . -name 'bs_jwt-*.gem')"
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 'bs/jwt'
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(__FILE__)
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/bs_jwt.gemspec ADDED
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'bs_jwt/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'bs_jwt'
9
+ spec.version = BsJwt::VERSION
10
+ spec.authors = ['Karol M']
11
+ spec.email = ['dmuhafc@gmail.com']
12
+
13
+ spec.summary = 'Simple library for verifying Auth0 JWTs.'
14
+ spec.homepage = 'http://buddy.buddyandselly.com'
15
+
16
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
17
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
18
+ if spec.respond_to?(:metadata)
19
+ # spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
20
+ else
21
+ raise 'RubyGems 2.0 or newer is required to protect against ' \
22
+ 'public gem pushes.'
23
+ end
24
+
25
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
26
+ f.match(%r{^(test|spec|features)/})
27
+ end
28
+ spec.bindir = 'exe'
29
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
30
+ spec.require_paths = ['lib']
31
+
32
+ spec.add_development_dependency 'bundler', '~> 1.16'
33
+ spec.add_development_dependency 'factory_bot'
34
+ spec.add_development_dependency 'pry-byebug'
35
+ spec.add_development_dependency 'rake', '~> 10.0'
36
+ spec.add_development_dependency 'rspec', '~> 3.0'
37
+ spec.add_development_dependency 'rubocop', '0.57.2'
38
+ spec.add_development_dependency 'webmock'
39
+
40
+ spec.add_dependency 'activesupport', '>= 4.0'
41
+ spec.add_dependency 'faraday', '>= 0.8'
42
+ spec.add_dependency 'json-jwt', '~> 1.9.4'
43
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ BsJwt.auth0_domain = ENV.fetch('AUTH0_DOMAIN')
4
+ # BsJwt.jwks_endpoint = '/.well-known/jwks.json'
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BsJwt
4
+ class Authentication
5
+ attr_accessor :roles, :display_name, :token, :expires_at, :email, :user_id, :issued_at
6
+
7
+ def self.from_jwt_payload(payload, jwt_token)
8
+ new(
9
+ roles: payload['https://buddy.buddyandselly.com/roles'],
10
+ display_name: payload['nickname'],
11
+ token: jwt_token,
12
+ expires_at: Time.at(payload['exp']),
13
+ email: payload['name'],
14
+ user_id: payload['sub'],
15
+ issued_at: Time.at(payload['iat'])
16
+ )
17
+ end
18
+
19
+ def initialize(attributes = {})
20
+ attributes = attributes.with_indifferent_access
21
+ @roles = attributes[:roles] || []
22
+ @display_name = attributes[:display_name]
23
+ @token = attributes[:token]
24
+ @expires_at = attributes[:expires_at]
25
+ @email = attributes[:email]
26
+ @user_id = attributes[:user_id]
27
+ @issued_at = attributes[:issued_at]
28
+ end
29
+
30
+ def has_role?(role) # rubocop:disable Naming/PredicateName
31
+ roles.include?(role)
32
+ end
33
+
34
+ def expired?
35
+ Time.now >= expires_at
36
+ end
37
+
38
+ def to_h
39
+ instance_values
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BsJwt
4
+ FactoryBot.define do
5
+ factory :bs_jwt_authentication, class: Authentication do
6
+ issued_at { 1.hour.ago }
7
+ expires_at { 1.hour.from_now }
8
+ user_id "auth0|#{SecureRandom.hex(8)}"
9
+ email 'test@buddyandselly.com'
10
+ display_name 'Max Mustermann'
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'factories/authentications'
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BsJwt
4
+ class Railtie < Rails::Railtie
5
+ rake_tasks do
6
+ load 'bs_jwt/tasks/install.rake'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :bs_jwt do
4
+ desc 'Stub an initializer for BS::JWT configuration.'
5
+ task :install do
6
+ raise 'Rails not loaded!' unless defined?(Rails)
7
+ source = File.join(Gem.loaded_specs['bs_jwt'].full_gem_path, 'config', 'initializers', 'bs_jwt.rb')
8
+ target = File.join(Rails.root, 'config', 'initializers', 'bs_jwt.rb')
9
+ if File.exist?(target)
10
+ STDOUT.puts "File #{target} exists, overwriting..."
11
+ else
12
+ STDOUT.puts "Generating new initializer at #{target}..."
13
+ end
14
+ FileUtils.cp(source, target)
15
+ end
16
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BsJwt
4
+ VERSION = '2.0.1'
5
+ end
data/lib/bs_jwt.rb ADDED
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bs_jwt/version'
4
+ require 'bs_jwt/authentication'
5
+ require 'bs_jwt/railtie' if defined?(Rails)
6
+ require 'json/jwt'
7
+ require 'faraday'
8
+ require 'active_support/core_ext'
9
+
10
+ ##
11
+ # Module BsJwt
12
+ # Used to decode, verify, and process JSON Web Tokens (JWTs) issued by Auth0
13
+ # in applications developed and used at the company Reverse-Retail GmbH
14
+ # (www.buddyandselly.com), Hamburg, Germany.
15
+ # BS stands for Buddy&Selly.
16
+ #
17
+ # The purpose of this library is to avoid code duplication among different
18
+ # Rails apps, such as Buddy, B&S Inventory, or B&S Packing.
19
+ module BsJwt
20
+ class BaseError < RuntimeError; end
21
+
22
+ class ConfigMissing < BaseError; end
23
+ class VerificationError < BaseError; end
24
+ class NetworkError < BaseError; end
25
+ class InvalidToken < BaseError; end
26
+
27
+ mattr_accessor :auth0_domain
28
+
29
+ DEFAULT_ENDPOINT = '/.well-known/jwks.json'
30
+
31
+ class << self
32
+ def verify_and_decode_auth0_hash!(auth0_hash)
33
+ raise ArgumentError, 'Auth0 Hash must be an instance of Hash' unless auth0_hash.is_a?(Hash)
34
+ jwt = auth0_hash.dig('credentials', 'id_token')
35
+ verify_and_decode!(jwt)
36
+ end
37
+
38
+ def verify_and_decode_auth0_hash(auth0_hash)
39
+ raise ArgumentError, 'Auth0 Hash must be an instance of Hash' unless auth0_hash.is_a?(Hash)
40
+ jwt = auth0_hash.dig('credentials', 'id_token')
41
+ verify_and_decode(jwt)
42
+ end
43
+
44
+ def verify_and_decode!(jwt)
45
+ raise InvalidToken, 'token is nil' if jwt.nil?
46
+ decoded = JSON::JWT.decode(jwt, jwks_key)
47
+ Authentication.from_jwt_payload(decoded, jwt)
48
+ rescue JSON::JWT::Exception
49
+ raise InvalidToken
50
+ end
51
+
52
+ def verify_and_decode(jwt)
53
+ return if jwt.nil?
54
+ decoded = JSON::JWT.decode(jwt, jwks_key)
55
+ Authentication.from_jwt_payload(decoded, jwt)
56
+ rescue JSON::JWT::Exception
57
+ nil
58
+ end
59
+
60
+ def jwks_key
61
+ @jwks_key ||= update_jwks
62
+ end
63
+
64
+ private
65
+
66
+ # Fetches and overwrites the JWKS
67
+ def update_jwks
68
+ check_config
69
+ fetch_jwks
70
+ end
71
+
72
+ def check_config
73
+ %i[auth0_domain].each do |key|
74
+ val = send(key)
75
+ next if val && (val.respond_to?(:empty?) && !val.empty?) # present
76
+ raise ConfigMissing, "#{key} is not set"
77
+ end
78
+ end
79
+
80
+ def fetch_jwks(domain: auth0_domain)
81
+ url = [domain, DEFAULT_ENDPOINT].join
82
+ url = 'https://' + url unless url =~ %r{https?://}
83
+ res = Faraday.get(url)
84
+ # raise if response code is not HTTP success
85
+ # Faraday's exception should fall through
86
+ raise(NetworkError, 'Fetching JWKS key failed') unless res.success?
87
+ JSON::JWK::Set.new(JSON.parse(res.body))
88
+ end
89
+ end
90
+ end
metadata ADDED
@@ -0,0 +1,207 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bs_jwt
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Karol M
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-07-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.16'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.16'
27
+ - !ruby/object:Gem::Dependency
28
+ name: factory_bot
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry-byebug
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '='
88
+ - !ruby/object:Gem::Version
89
+ version: 0.57.2
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '='
95
+ - !ruby/object:Gem::Version
96
+ version: 0.57.2
97
+ - !ruby/object:Gem::Dependency
98
+ name: webmock
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
+ - !ruby/object:Gem::Dependency
112
+ name: activesupport
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '4.0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '4.0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: faraday
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0.8'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0.8'
139
+ - !ruby/object:Gem::Dependency
140
+ name: json-jwt
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: 1.9.4
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: 1.9.4
153
+ description:
154
+ email:
155
+ - dmuhafc@gmail.com
156
+ executables: []
157
+ extensions: []
158
+ extra_rdoc_files: []
159
+ files:
160
+ - ".gitignore"
161
+ - ".gitlab-ci.yml"
162
+ - ".rspec"
163
+ - ".rubocop.yml"
164
+ - ".ruby-version"
165
+ - ".travis.yml"
166
+ - CHANGELOG.md
167
+ - Gemfile
168
+ - Gemfile.lock
169
+ - LICENSE
170
+ - README.md
171
+ - Rakefile
172
+ - bin/build_and_publish
173
+ - bin/console
174
+ - bin/setup
175
+ - bs_jwt.gemspec
176
+ - config/initializers/bs_jwt.rb
177
+ - lib/bs_jwt.rb
178
+ - lib/bs_jwt/authentication.rb
179
+ - lib/bs_jwt/factories.rb
180
+ - lib/bs_jwt/factories/authentications.rb
181
+ - lib/bs_jwt/railtie.rb
182
+ - lib/bs_jwt/tasks/install.rake
183
+ - lib/bs_jwt/version.rb
184
+ homepage: http://buddy.buddyandselly.com
185
+ licenses: []
186
+ metadata: {}
187
+ post_install_message:
188
+ rdoc_options: []
189
+ require_paths:
190
+ - lib
191
+ required_ruby_version: !ruby/object:Gem::Requirement
192
+ requirements:
193
+ - - ">="
194
+ - !ruby/object:Gem::Version
195
+ version: '0'
196
+ required_rubygems_version: !ruby/object:Gem::Requirement
197
+ requirements:
198
+ - - ">="
199
+ - !ruby/object:Gem::Version
200
+ version: '0'
201
+ requirements: []
202
+ rubyforge_project:
203
+ rubygems_version: 2.7.7
204
+ signing_key:
205
+ specification_version: 4
206
+ summary: Simple library for verifying Auth0 JWTs.
207
+ test_files: []