Codebase list ruby-omniauth-auth0 / upstream/2.2.0
Import upstream version 2.2.0, md5 88dbdfad744b46d6b67891c4102c1eec Debian Janitor 4 years ago
24 changed file(s) with 1208 addition(s) and 131 deletion(s). Raw diff Collapse all Expand all
0 version: 2.1
1 jobs:
2 run-tests:
3 docker:
4 - image: circleci/ruby:2.4.6-jessie
5 steps:
6 - checkout
7 - restore_cache:
8 keys:
9 - gems-v2-{{ checksum "Gemfile.lock" }}
10 - gems-v2-
11 - run: bundle check || bundle install
12 - persist_to_workspace:
13 root: .
14 paths:
15 - Gemfile
16 - Gemfile.lock
17 - save_cache:
18 key: gems-v2--{{ checksum "Gemfile.lock" }}
19 paths:
20 - vendor/bundle
21 - run: bundle exec rake spec
22 snyk:
23 docker:
24 - image: snyk/snyk-cli:rubygems
25 steps:
26 - attach_workspace:
27 at: .
28 - run: snyk test
29 - run:
30 command: |
31 if [[ "${CIRCLE_BRANCH}" == "master" ]]
32 then
33 snyk monitor --org=auth0-sdks
34 fi
35 when: always
36
37 workflows:
38 tests:
39 jobs:
40 - run-tests
41 snyk:
42 jobs:
43 - run-tests
44 - snyk:
45 # Must define SNYK_TOKEN env
46 context: snyk-env
47 requires:
48 - run-tests
0 In order to efficiently and accurately address your issue or feature request, please read through the template below and answer all relevant questions. Your additional work here is greatly appreciated and will help us respond as quickly as possible. Please delete any sections or questions below that do not pertain to this request.
1
2 For general support or usage questions, please use the [Auth0 Community](https://community.auth0.com/) or [Auth0 Support](https://support.auth0.com.).
3
4 ### Description
5
6 Description of the bug or feature request and why it's a problem. Consider including:
7
8 - The use case or overall problem you're trying to solve
9 - Information about when the problem started
10
11 ### Prerequisites
12
13 * [ ] I have read the [Auth0 contribution guidelines](https://github.com/auth0/open-source-template/blob/master/GENERAL-CONTRIBUTING.md)
14 * [ ] I have read the [Auth0 Code of Conduct](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md)
15 * [ ] Did you check the [documentation](https://auth0.com/docs/quickstart/webapp/rails)?
16 * [ ] Did you check [Auth0 Community](https://community.auth0.com/tags/rails)?
17 * [ ] Are you reporting this to the correct repository? This strategy relies on [OmniAuth](https://github.com/omniauth/omniauth) and the [OmniAuth OAuth2](https://github.com/omniauth/omniauth-oauth2) strategy.
18 * [ ] Are there any related or duplicate [Issues](https://github.com/auth0/omniauth-auth0/issues) or [PRs](https://github.com/auth0/omniauth-auth0/pulls) for this issue?
19
20 ### Environment
21
22 Please provide the following:
23
24 * OmniAuth-Auth0 version:
25 * Ruby version:
26 * Rails veresion:
27 * Browser version, if applicable:
28 * Additional gems that might be affecting your instance:
29
30 ### Reproduction
31
32 Detail the steps taken to reproduce this error and note if this issue can be reproduced consistently or if it is intermittent.
33
34 Please include:
35
36 - Log files (redact/remove sensitive information)
37 - Application settings (redact/remove sensitive information)
38 - Screenshots, if helpful
0 ### Changes
1
2 Please describe both what is changing and why this is important. Include:
3
4 - Endpoints added, deleted, deprecated, or changed
5 - Classes and methods added, deleted, deprecated, or changed
6 - Screenshots of new or changed UI, if applicable
7 - A summary of usage if this is a new feature or change to a public API (this should also be added to relevant documentation once released)
8
9 ### References
10
11 Please include relevant links supporting this change such as a:
12
13 - support ticket
14 - community post
15 - StackOverflow post
16 - support forum thread
17 - related GitHub issue in this or another repo
18
19 ### Testing
20
21 Please describe how this can be tested by reviewers. Be specific about anything not tested and reasons why. If this library has unit and/or integration testing, tests should be added for new functionality and existing tests should complete without errors.
22
23 * [ ] This change adds unit test coverage
24 * [ ] This change has been tested on the latest version of the platform/language or why not
25
26 ### Checklist
27
28 * [ ] I have read the [Auth0 contribution guidelines](https://github.com/auth0/open-source-template/blob/master/GENERAL-CONTRIBUTING.md)
29 * [ ] I have read the [Auth0 Code of Conduct](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md)
30 * [ ] All existing and new tests complete without errors
31 * [ ] All code quality tools/guidelines in the [CONTRIBUTING documentation](CONTRIBUTING.md) have been run/followed
00 .ruby-version
11 coverage
2 Gemfile.lock
32 *.gem
43
54 .#*
65 .env
76 log/
8 tmp/
7 tmp/
8
9 ## Environment normalization:
10 /.bundle
11 /vendor/bundle
+0
-6
.travis.yml less more
0 language: ruby
1 rvm:
2 - 2.2.5
3 branches:
4 only:
5 - master
00 # Change Log
1
2 ## [v2.2.0](https://github.com/auth0/omniauth-auth0/tree/v2.2.0) (2018-04-18)
3 [Full Changelog](https://github.com/auth0/omniauth-auth0/compare/v2.1.0...v2.2.0)
4
5 **Closed issues**
6 - It supports custom domain? [\#71](https://github.com/auth0/omniauth-auth0/issues/71)
7 - Valid Login, No Details: email=nil image=nil name="github|38257089" nickname=nil [\#70](https://github.com/auth0/omniauth-auth0/issues/70)
8
9 **Added**
10 - Custom issuer [\#77](https://github.com/auth0/omniauth-auth0/pull/77) ([ryan-rosenfeld](https://github.com/ryan-rosenfeld))
11 - Add telemetry to token endpoint [\#74](https://github.com/auth0/omniauth-auth0/pull/74) ([joshcanhelp](https://github.com/joshcanhelp))
12
13 **Changed**
14 - Remove telemetry from authorize URL [\#75](https://github.com/auth0/omniauth-auth0/pull/75) ([joshcanhelp](https://github.com/joshcanhelp))
15
16 ## [v2.1.0](https://github.com/auth0/omniauth-auth0/tree/v2.1.0) (2018-10-30)
17 [Full Changelog](https://github.com/auth0/omniauth-auth0/compare/v2.0.0...v2.1.0)
18
19 **Closed issues**
20 - URL should be spelled uppercase outside of code [\#64](https://github.com/auth0/omniauth-auth0/issues/64)
21 - Add prompt=none authorization param handler [\#58](https://github.com/auth0/omniauth-auth0/issues/58)
22 - Could not find a valid mapping for path "/auth/oauth2/callback" [\#56](https://github.com/auth0/omniauth-auth0/issues/56)
23 - I had to downgrade my gems to use this strategy :-( [\#53](https://github.com/auth0/omniauth-auth0/issues/53)
24 - CSRF detected [\#49](https://github.com/auth0/omniauth-auth0/issues/49)
25 - /auth/:provider route not registered? [\#47](https://github.com/auth0/omniauth-auth0/issues/47)
26
27 **Added**
28 - Add ID token validation [\#62](https://github.com/auth0/omniauth-auth0/pull/62) ([joshcanhelp](https://github.com/joshcanhelp))
29 - Silent authentication [\#59](https://github.com/auth0/omniauth-auth0/pull/59) ([batalla3692](https://github.com/batalla3692))
30 - Pass connection parameter to auth0 [\#54](https://github.com/auth0/omniauth-auth0/pull/54) ([tomgi](https://github.com/tomgi))
31
32 **Changed**
33 - Update to omniauth-oauth2 [\#55](https://github.com/auth0/omniauth-auth0/pull/55) ([chills42](https://github.com/chills42))
34
35 **Fixed**
36 - Fix Rubocop errors [\#66](https://github.com/auth0/omniauth-auth0/pull/66) ([joshcanhelp](https://github.com/joshcanhelp))
37 - Fix minute bug in README.md [\#63](https://github.com/auth0/omniauth-auth0/pull/63) ([rahuldess](https://github.com/rahuldess))
138
239 ## [v2.0.0](https://github.com/auth0/omniauth-auth0/tree/v2.0.0) (2017-01-25)
340 [Full Changelog](https://github.com/auth0/omniauth-auth0/compare/v1.4.1...v2.0.0)
441
542 Updated library to handle OIDC conformant clients and OAuth2 features in Auth0.
6 This affects how the `credentials` and `info` attributes are populated since the payload of /oauth/token and /userinfo are differnt when using OAuth2/OIDC features.
43 This affects how the `credentials` and `info` attributes are populated since the payload of /oauth/token and /userinfo are different when using OAuth2/OIDC features.
744
845 The `credentials` hash will always have an `access_token` and might have a `refresh_token` (if it's allowed in your API settings in Auth0 dashboard and requested using `offline_access` scope) and an `id_token` (scope `openid` is needed for Auth0 to return it).
946
1552 - image: `picture` attribute in userinfo response.
1653
1754 Also in `extra` will have in `raw_info` the full /userinfo response.
55
56 **Fixed**
57 - Use image attribute of omniauth instead of picture [\#45](https://github.com/auth0/omniauth-auth0/pull/45) ([hzalaz](https://github.com/hzalaz))
58 - Rework strategy to handle OAuth and OIDC [\#44](https://github.com/auth0/omniauth-auth0/pull/44) ([hzalaz](https://github.com/hzalaz))
59 - lock v10 update, dependencies update [\#41](https://github.com/auth0/omniauth-auth0/pull/41) ([Amialc](https://github.com/Amialc))
60
61 ## [v1.4.2](https://github.com/auth0/omniauth-auth0/tree/v1.4.2) (2016-06-13)
62 [Full Changelog](https://github.com/auth0/omniauth-auth0/compare/v1.4.1...v1.4.2)
63
64 **Added**
65 - Link to OmniAuth site [\#36](https://github.com/auth0/omniauth-auth0/pull/36) ([jghaines](https://github.com/jghaines))
66 - add ssl fix to RoR example [\#31](https://github.com/auth0/omniauth-auth0/pull/31) ([Amialc](https://github.com/Amialc))
67 - Update LICENSE [\#17](https://github.com/auth0/omniauth-auth0/pull/17) ([aguerere](https://github.com/aguerere))
68
69 **Changed**
70 - Update lock to version 9 [\#34](https://github.com/auth0/omniauth-auth0/pull/34) ([Annyv2](https://github.com/Annyv2))
71 - Update Gemfile [\#22](https://github.com/auth0/omniauth-auth0/pull/22) ([Annyv2](https://github.com/Annyv2))
72 - Update lock [\#15](https://github.com/auth0/omniauth-auth0/pull/15) ([Annyv2](https://github.com/Annyv2))
73
74 **Fixed**
75 - Fix setup [\#38](https://github.com/auth0/omniauth-auth0/pull/38) ([deepak](https://github.com/deepak))
76 - Added missing instruction [\#30](https://github.com/auth0/omniauth-auth0/pull/30) ([Annyv2](https://github.com/Annyv2))
77 - Fixes undefined Auth0Lock issue [\#28](https://github.com/auth0/omniauth-auth0/pull/28) ([Annyv2](https://github.com/Annyv2))
78 - Update Readme [\#27](https://github.com/auth0/omniauth-auth0/pull/27) ([Annyv2](https://github.com/Annyv2))
79
1880
1981 ## [v1.4.1](https://github.com/auth0/omniauth-auth0/tree/v1.4.1) (2015-11-18)
2082 [Full Changelog](https://github.com/auth0/omniauth-auth0/compare/v1.4.0...v1.4.1)
0 # Code of Conduct
1
2 Please see [Auth0's Code of Conduct](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md) for information on contributing to this repo.
0 # Contribution
1
2 **Thank you in advance for your contribution!**
3
4 Please read [Auth0's contribution guidelines](https://github.com/auth0/open-source-template/blob/master/GENERAL-CONTRIBUTING.md) before beginning work on your contribution here.
5
6 ## Environment setup
7
8 The best way we've found to develop gems locally is by using a local setting for your Bundler config. First, checkout the project locally:
9
10 ```bash
11 $ pwd
12 /PROJECT_ROOT/
13 $ mkdir vendor # if one does not exist
14 $ echo "/vendor/" >> .gitignore
15 $ git clone git@github.com:auth0/omniauth-auth0.git vendor/omniauth-auth0
16 Cloning into 'vendor/omniauth-auth0'...
17 ```
18
19 Now, run the following command in your project root directory:
20
21 ```bash
22 $ bundle config --local local.omniauth-auth0 /PROJECT_ROOT/vendor/omniauth-auth0
23 You are replacing the current local value of local.omniauth-auth0, which is currently nil
24 $ bundle config
25 Settings are listed in order of priority. The top value will be used.
26 local.omniauth-auth0
27 Set for your local app (/PROJECT_ROOT/.bundle/config): "/PROJECT_ROOT/vendor/omniauth-auth0"
28 ```
29
30 Finally, add or change the gem include to add a `github:` param:
31
32 ```ruby
33 source 'https://rubygems.org'
34 # ...
35 # OmniAuth strategy for authenticating with Auth0
36 gem 'omniauth-auth0', github: 'auth0/omniauth-auth0'
37 #..
38 ```
39
40 Now you should be able to make changes locally and have them reflected in your test app. Keep in mind you'll need to restart your app between changes.
41
42 [Great explanation for why this setup works well](https://rossta.net/blog/how-to-specify-local-ruby-gems-in-your-gemfile.html).
43
44 ## Testing
45
46 Tests should be added for additional or modified functionality and all tests should run successfully before submitting a PR.
47
48 ### Adding tests
49
50 All new tests should be added to the `/spec/omniauth` directory. Testing resources, like JSON fixtures, should be added to the `/spec/resources` directory.
51
52 ### Running tests
53
54 Running tests is as simple as:
55
56 ```bash
57 $ bundle exec rake spec
58 ```
59
60 ## Documentation
61
62 Documentation for this gem is primarily done at the code level. All new methods should include a docblock at least.
63
64 ## Code quality tools
65
66 Code quality is enforced across the entire gem with Rubocop:
67
68 ```bash
69 $ bundle exec rake rubocop
70 ```
0 source 'http://rubygems.org'
0 source 'https://rubygems.org'
11
22 gemspec
33
44 gem 'gem-release'
5 gem 'jwt'
56 gem 'rake'
67
78 group :development do
89 gem 'dotenv'
910 gem 'pry'
11 gem 'rubocop', require: false
1012 gem 'shotgun'
1113 gem 'sinatra'
1214 gem 'thin'
1719 gem 'listen', '~> 3.1.5'
1820 gem 'rack-test'
1921 gem 'rspec', '~> 3.5'
20 gem 'rubocop', '>= 0.30', platforms: [
21 :ruby_19, :ruby_20, :ruby_21, :ruby_22
22 ]
22 gem 'codecov', require: false
2323 gem 'simplecov'
2424 gem 'webmock'
2525 end
0 PATH
1 remote: .
2 specs:
3 omniauth-auth0 (2.2.0)
4 omniauth-oauth2 (~> 1.5)
5
6 GEM
7 remote: https://rubygems.org/
8 specs:
9 addressable (2.6.0)
10 public_suffix (>= 2.0.2, < 4.0)
11 ast (2.4.0)
12 codecov (0.1.14)
13 json
14 simplecov
15 url
16 coderay (1.1.2)
17 crack (0.4.3)
18 safe_yaml (~> 1.0.0)
19 daemons (1.3.1)
20 diff-lcs (1.3)
21 docile (1.3.1)
22 dotenv (2.7.2)
23 eventmachine (1.2.7)
24 faraday (0.15.4)
25 multipart-post (>= 1.2, < 3)
26 ffi (1.10.0)
27 formatador (0.2.5)
28 gem-release (2.0.1)
29 guard (2.15.0)
30 formatador (>= 0.2.4)
31 listen (>= 2.7, < 4.0)
32 lumberjack (>= 1.0.12, < 2.0)
33 nenv (~> 0.1)
34 notiffany (~> 0.0)
35 pry (>= 0.9.12)
36 shellany (~> 0.0)
37 thor (>= 0.18.1)
38 guard-compat (1.2.1)
39 guard-rspec (4.7.3)
40 guard (~> 2.1)
41 guard-compat (~> 1.1)
42 rspec (>= 2.99.0, < 4.0)
43 hashdiff (0.3.8)
44 hashie (3.6.0)
45 jaro_winkler (1.5.2)
46 json (2.2.0)
47 jwt (2.1.0)
48 listen (3.1.5)
49 rb-fsevent (~> 0.9, >= 0.9.4)
50 rb-inotify (~> 0.9, >= 0.9.7)
51 ruby_dep (~> 1.2)
52 lumberjack (1.0.13)
53 method_source (0.9.2)
54 multi_json (1.13.1)
55 multi_xml (0.6.0)
56 multipart-post (2.0.0)
57 mustermann (1.0.3)
58 nenv (0.3.0)
59 notiffany (0.1.1)
60 nenv (~> 0.1)
61 shellany (~> 0.0)
62 oauth2 (1.4.1)
63 faraday (>= 0.8, < 0.16.0)
64 jwt (>= 1.0, < 3.0)
65 multi_json (~> 1.3)
66 multi_xml (~> 0.5)
67 rack (>= 1.2, < 3)
68 omniauth (1.9.0)
69 hashie (>= 3.4.6, < 3.7.0)
70 rack (>= 1.6.2, < 3)
71 omniauth-oauth2 (1.6.0)
72 oauth2 (~> 1.1)
73 omniauth (~> 1.9)
74 parallel (1.17.0)
75 parser (2.6.2.1)
76 ast (~> 2.4.0)
77 pry (0.12.2)
78 coderay (~> 1.1.0)
79 method_source (~> 0.9.0)
80 psych (3.1.0)
81 public_suffix (3.0.3)
82 rack (2.0.7)
83 rack-protection (2.0.5)
84 rack
85 rack-test (1.1.0)
86 rack (>= 1.0, < 3)
87 rainbow (3.0.0)
88 rake (12.3.2)
89 rb-fsevent (0.10.3)
90 rb-inotify (0.10.0)
91 ffi (~> 1.0)
92 rspec (3.8.0)
93 rspec-core (~> 3.8.0)
94 rspec-expectations (~> 3.8.0)
95 rspec-mocks (~> 3.8.0)
96 rspec-core (3.8.0)
97 rspec-support (~> 3.8.0)
98 rspec-expectations (3.8.2)
99 diff-lcs (>= 1.2.0, < 2.0)
100 rspec-support (~> 3.8.0)
101 rspec-mocks (3.8.0)
102 diff-lcs (>= 1.2.0, < 2.0)
103 rspec-support (~> 3.8.0)
104 rspec-support (3.8.0)
105 rubocop (0.67.2)
106 jaro_winkler (~> 1.5.1)
107 parallel (~> 1.10)
108 parser (>= 2.5, != 2.5.1.1)
109 psych (>= 3.1.0)
110 rainbow (>= 2.2.2, < 4.0)
111 ruby-progressbar (~> 1.7)
112 unicode-display_width (>= 1.4.0, < 1.6)
113 ruby-progressbar (1.10.0)
114 ruby_dep (1.5.0)
115 safe_yaml (1.0.5)
116 shellany (0.0.1)
117 shotgun (0.9.2)
118 rack (>= 1.0)
119 simplecov (0.16.1)
120 docile (~> 1.1)
121 json (>= 1.8, < 3)
122 simplecov-html (~> 0.10.0)
123 simplecov-html (0.10.2)
124 sinatra (2.0.5)
125 mustermann (~> 1.0)
126 rack (~> 2.0)
127 rack-protection (= 2.0.5)
128 tilt (~> 2.0)
129 thin (1.7.2)
130 daemons (~> 1.0, >= 1.0.9)
131 eventmachine (~> 1.0, >= 1.0.4)
132 rack (>= 1, < 3)
133 thor (0.20.3)
134 tilt (2.0.9)
135 unicode-display_width (1.5.0)
136 url (0.3.2)
137 webmock (3.5.1)
138 addressable (>= 2.3.6)
139 crack (>= 0.3.2)
140 hashdiff
141
142 PLATFORMS
143 ruby
144
145 DEPENDENCIES
146 bundler (~> 1.9)
147 codecov
148 dotenv
149 gem-release
150 guard-rspec
151 jwt
152 listen (~> 3.1.5)
153 omniauth-auth0!
154 pry
155 rack-test
156 rake
157 rspec (~> 3.5)
158 rubocop
159 shotgun
160 simplecov
161 sinatra
162 thin
163 webmock
164
165 BUNDLED WITH
166 1.17.3
0 [![Build Status](https://travis-ci.org/auth0/omniauth-auth0.svg)](https://travis-ci.org/auth0/omniauth-auth0)
1
20 # OmniAuth Auth0
31
4 This is the official [OmniAuth](https://github.com/intridea/omniauth) strategy for authenticating to [Auth0](https://auth0.com).
2 An [OmniAuth](https://github.com/intridea/omniauth) strategy for authenticating with [Auth0](https://auth0.com). This strategy is based on the [OmniAuth OAuth2](https://github.com/omniauth/omniauth-oauth2) strategy.
53
6 ## Installing
4 [![CircleCI](https://img.shields.io/circleci/project/github/auth0/omniauth-auth0/master.svg)](https://circleci.com/gh/auth0/omniauth-auth0)
5 [![codecov](https://codecov.io/gh/auth0/omniauth-auth0/branch/master/graph/badge.svg)](https://codecov.io/gh/auth0/omniauth-auth0)
6 [![Gem Version](https://badge.fury.io/rb/omniauth-auth0.svg)](https://badge.fury.io/rb/omniauth-auth0)
7 [![MIT licensed](https://img.shields.io/dub/l/vibe-d.svg?style=flat)](https://github.com/auth0/omniauth-auth0/blob/master/LICENSE)
78
8 Add to your `Gemfile`:
9 ## Table of Contents
10
11 - [Documentation](#documentation)
12 - [Installation](#installation)
13 - [Getting Started](#getting-started)
14 - [Contribution](#contribution)
15 - [Support + Feedback](#support--feedback)
16 - [Vulnerability Reporting](#vulnerability-reporting)
17 - [What is Auth0](#what-is-auth0)
18 - [License](#license)
19
20 ## Documentation
21
22 - [Ruby on Rails Quickstart](https://auth0.com/docs/quickstart/webapp/rails)
23 - [Sample projects](https://github.com/auth0-samples/auth0-rubyonrails-sample)
24
25 ## Installation
26
27 Add the following line to your `Gemfile`:
928
1029 ```ruby
1130 gem 'omniauth-auth0'
1231 ```
1332
14 Then `bundle install`.
33 Then install:
1534
16 ## Usage
17
18 ### Rails
19
20 ```ruby
21 Rails.application.config.middleware.use OmniAuth::Builder do
22 provider :auth0, ENV['AUTH0_CLIENT_ID'], ENV['AUTH0_CLIENT_SECRET'], ENV['AUTH0_DOMAIN']
23 end
35 ```bash
36 $ bundle install
2437 ```
2538
26 Then to redirect to your tenant's hosted login page:
39 See our [contributing guide](CONTRIBUTING.md) for information on local installation for development.
2740
28 ```ruby
29 redirect_to '/auth/auth0'
30 ```
41 ## Getting Started
3142
32 ### Sinatra
43 To start processing authentication requests, the following steps must be performed:
3344
34 ```ruby
35 use OmniAuth::Builder do
36 provider :auth0, ENV['AUTH0_CLIENT_ID'], ENV['AUTH0_CLIENT_SECRET'], ENV['AUTH0_DOMAIN']
37 end
38 ```
45 1. Initialize the strategy
46 2. Configure the callback controller
47 3. Add the required routes
48 4. Trigger an authentication request
3949
40 Then to redirect to your tenant's hosted login page:
50 All of these tasks and more are covered in our [Ruby on Rails Quickstart](https://auth0.com/docs/quickstart/webapp/rails).
4151
42 ```ruby
43 redirect to('/auth/auth0')
44 ```
52 ### Additional authentication parameters
4553
46 > You can customize your hosted login page in your [Auth0 Dashboard](https://manage.auth0.com/#/login_page)
47
48 ### Auth parameters
49
50 To send additional parameters during login you can specify them when you register the provider
54 To send additional parameters during login, you can specify them when you register the provider:
5155
5256 ```ruby
5357 provider
6367 }
6468 ```
6569
66 that will tell it to send those parameters on every Auth request.
70 ... which will tell the strategy to send those parameters on every Auth request.
6771
68 Or you can do it for a specific Auth request by adding them in the query parameter of the redirect url:
72 Or you can do it for a specific authentication request by adding them to the query parameters of the redirect URL. Allowed parameters are `connection` and `prompt`:
6973
7074 ```ruby
7175 redirect_to '/auth/auth0?connection=google-oauth2'
76 redirect_to '/auth/auth0?prompt=none'
7277 ```
7378
74 ### Auth Hash
79 ### Authentication hash
7580
76 Auth0 strategy will have the standard OmniAuth hash attributes:
81 The Auth0 strategy will provide the standard OmniAuth hash attributes:
7782
78 - provider: the name of the strategy, in this case `auth0`
79 - uid: the user identifier
80 - info: the result of the call to /userinfo using OmniAuth standard attributes
81 - credentials: Auth0 tokens, at least will have an access_token but can eventually have refresh_token and/or id_token
82 - extra: Additional info obtained from calling /userinfo in the attribute `raw_info`
83 - `:provider` - the name of the strategy, in this case `auth0`
84 - `:uid` - the user identifier
85 - `:info` - the result of the call to `/userinfo` using OmniAuth standard attributes
86 - `:credentials` - tokens requested and data
87 - `:extra` - Additional info obtained from calling `/userinfo` in the `:raw_info` property
8388
8489 ```ruby
85 {
86 :provider => 'auth0',
87 :uid => 'google-oauth2|this-is-the-google-id',
88 :info => {
89 :name => 'John Foo',
90 :email => 'johnfoo@example.org',
91 :nickname => 'john',
92 :image => 'https://example.org/john.jpg'
93 },
94 :credentials => {
95 :token => 'XdDadllcas2134rdfdsI',
96 :expires_at => 1485373937,
97 :expires => true,
98 :refresh_token => 'aKNajdjfj123nBasd',
99 :id_token => 'eyJhbGciOiJIUzI1NiIsImN0eSI6IkpXVCJ9.eyJuYW1lIjoiSm9obiBGb28ifQ.lxAiy1rqve8ZHQEQVehUlP1sommPHVJDhgPgFPnDosg',
100 :token_type => 'bearer',
101 },
102 :extra => {
103 :raw_info => {
104 :email => 'johnfoo@example.org',
105 :email_verified => 'true',
106 :name => 'John Foo',
107 :picture => 'https://example.org/john.jpg',
108 :user_id => 'google-oauth2|this-is-the-google-id',
109 :nickname => 'john',
110 :created_at: '2014-07-15T17:19:50.387Z'
111 }
112 }
113 }
90 {
91 :provider => 'auth0',
92 :uid => 'auth0|USER_ID',
93 :info => {
94 :name => 'John Foo',
95 :email => 'johnfoo@example.org',
96 :nickname => 'john',
97 :image => 'https://example.org/john.jpg'
98 },
99 :credentials => {
100 :token => 'ACCESS_TOKEN',
101 :expires_at => 1485373937,
102 :expires => true,
103 :refresh_token => 'REFRESH_TOKEN',
104 :id_token => 'JWT_ID_TOKEN',
105 :token_type => 'bearer',
106 },
107 :extra => {
108 :raw_info => {
109 :email => 'johnfoo@example.org',
110 :email_verified => 'true',
111 :name => 'John Foo',
112 :picture => 'https://example.org/john.jpg',
113 :user_id => 'auth0|USER_ID',
114 :nickname => 'john',
115 :created_at => '2014-07-15T17:19:50.387Z'
116 }
117 }
118 }
114119 ```
115120
116 ### ActionDispatch::Cookies::CookieOverflow issue
121 ## Contribution
117122
118 If you are getting this error it means that you are using Cookie sessions and since you are storing the whole profile it overflows the max-size of 4K.
123 We appreciate feedback and contribution to this repo! Before you get started, please see the following:
119124
120 You can change to use In-Memory store for development as follows:
125 - [Auth0's contribution guidelines](https://github.com/auth0/open-source-template/blob/master/GENERAL-CONTRIBUTING.md)
126 - [Auth0's Code of Conduct](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md)
127 - [This repo's contribution guide](CONTRIBUTING.md)
121128
122 # /config/initializers/session_store.rb
123 CrazyApp::Application.config.session_store :cache_store
129 ## Support + Feedback
124130
125 # /config/environments/development.rb
126 config.cache_store = :memory_store
127131
128 ## Documentation
132 - Use [Community](https://community.auth0.com/) for usage, questions, specific cases.
133 - Use [Issues](https://github.com/auth0/omniauth-auth0/issues) here for code-level support and bug reports.
134 - Paid customers can use [Support](https://support.auth0.com/) to submit a trouble ticket for production-affecting issues.
129135
130 For more information about [auth0](http://auth0.com) contact our [documentation page](http://docs.auth0.com/).
136 ## Vulnerability Reporting
131137
132 ## Issue Reporting
138 Please do not report security vulnerabilities on the public GitHub issue tracker. The [Responsible Disclosure Program](https://auth0.com/whitehat) details the procedure for disclosing security issues.
133139
134 If you have found a bug or if you have a feature request, please report them at this repository issues section. Please do not report security vulnerabilities on the public GitHub issue tracker. The [Responsible Disclosure Program](https://auth0.com/whitehat) details the procedure for disclosing security issues.
140 ## What is Auth0?
135141
136 ## Author
142 Auth0 helps you to easily:
137143
138 [Auth0](https://auth0.com)
144 - implement authentication with multiple identity providers, including social (e.g., Google, Facebook, Microsoft, LinkedIn, GitHub, Twitter, etc), or enterprise (e.g., Windows Azure AD, Google Apps, Active Directory, ADFS, SAML, etc.)
145 - log in users with username/password databases, passwordless, or multi-factor authentication
146 - link multiple user accounts together
147 - generate signed JSON Web Tokens to authorize your API calls and flow the user identity securely
148 - access demographics and analytics detailing how, when, and where users are logging in
149 - enrich user profiles from other data sources using customizable JavaScript rules
150
151 [Why Auth0?](https://auth0.com/why-auth0)
139152
140153 ## License
141154
142 This project is licensed under the MIT license. See the [LICENSE](LICENSE) file for more info.
155 The OmniAuth Auth0 strategy is licensed under MIT - [LICENSE](LICENSE)
99 RuboCop::RakeTask.new
1010 rescue LoadError
1111 task :rubocop do
12 $stderr.puts 'Rubocop is disabled'
12 warn 'Rubocop is disabled'
1313 end
1414 end
1515
2222 end
2323
2424 desc 'Run specs'
25 task default: [:spec, :rubocop]
25 task default: %i[spec rubocop]
2626 task test: :spec
2727 task :guard do
2828 system 'bundle exec guard'
0 coverage:
1 precision: 2
2 round: down
3 range: "60...100"
4 status:
5 project:
6 default:
7 enabled: true
8 target: auto
9 threshold: 5%
10 if_no_uploads: error
11 patch:
12 default:
13 enabled: true
14 target: 80%
15 threshold: 30%
16 if_no_uploads: error
17 changes:
18 default:
19 enabled: true
20 if_no_uploads: error
21 comment: false
0 require 'base64'
1 require 'uri'
2 require 'json'
3 require 'omniauth'
4
5 module OmniAuth
6 module Auth0
7 # JWT Validator class
8 class JWTValidator
9 attr_accessor :issuer, :domain
10
11 # Initializer
12 # @param options object
13 # options.domain - Application domain.
14 # options.issuer - Application issuer (optional).
15 # options.client_id - Application Client ID.
16 # options.client_secret - Application Client Secret.
17 def initialize(options)
18 @domain = uri_string(options.domain)
19
20 # Use custom issuer if provided, otherwise use domain
21 @issuer = @domain
22 @issuer = uri_string(options.issuer) if options.respond_to?(:issuer)
23
24 @client_id = options.client_id
25 @client_secret = options.client_secret
26 end
27
28 # Decode a JWT.
29 # @param jwt string - JWT to decode.
30 # @return hash - The decoded token, if there were no exceptions.
31 # @see https://github.com/jwt/ruby-jwt
32 def decode(jwt)
33 head = token_head(jwt)
34
35 # Make sure the algorithm is supported and get the decode key.
36 decode_key = @client_secret
37 if head[:alg] == 'RS256'
38 decode_key = rs256_decode_key(head[:kid])
39 elsif head[:alg] != 'HS256'
40 raise JWT::VerificationError, :id_token_alg_unsupported
41 end
42
43 # Docs: https://github.com/jwt/ruby-jwt#algorithms-and-usage
44 JWT.decode(jwt, decode_key, true, decode_opts(head[:alg]))
45 end
46
47 # Get the decoded head segment from a JWT.
48 # @return hash - The parsed head of the JWT passed, empty hash if not.
49 def token_head(jwt)
50 jwt_parts = jwt.split('.')
51 return {} if blank?(jwt_parts) || blank?(jwt_parts[0])
52
53 json_parse(Base64.decode64(jwt_parts[0]))
54 end
55
56 # Get the JWKS from the issuer and return a public key.
57 # @param x5c string - X.509 certificate chain from a JWKS.
58 # @return key - The X.509 certificate public key.
59 def jwks_public_cert(x5c)
60 x5c = Base64.decode64(x5c)
61
62 # https://docs.ruby-lang.org/en/2.4.0/OpenSSL/X509/Certificate.html
63 OpenSSL::X509::Certificate.new(x5c).public_key
64 end
65
66 # Return a specific key from a JWKS object.
67 # @param key string - Key to find in the JWKS.
68 # @param kid string - Key ID to identify the right JWK.
69 # @return nil|string
70 def jwks_key(key, kid)
71 return nil if blank?(jwks[:keys])
72
73 matching_jwk = jwks[:keys].find { |jwk| jwk[:kid] == kid }
74 matching_jwk[key] if matching_jwk
75 end
76
77 private
78
79 # Get the JWT decode options
80 # Docs: https://github.com/jwt/ruby-jwt#add-custom-header-fields
81 # @return hash
82 def decode_opts(alg)
83 {
84 algorithm: alg,
85 leeway: 30,
86 verify_expiration: true,
87 verify_iss: true,
88 iss: @issuer,
89 verify_aud: true,
90 aud: @client_id,
91 verify_not_before: true
92 }
93 end
94
95 def rs256_decode_key(kid)
96 jwks_x5c = jwks_key(:x5c, kid)
97 raise JWT::VerificationError, :jwks_missing_x5c if jwks_x5c.nil?
98
99 jwks_public_cert(jwks_x5c.first)
100 end
101
102 # Get a JWKS from the domain
103 # @return void
104 def jwks
105 jwks_uri = URI(@domain + '.well-known/jwks.json')
106 @jwks ||= json_parse(Net::HTTP.get(jwks_uri))
107 end
108
109 # Rails Active Support blank method.
110 # @param obj object - Object to check for blankness.
111 # @return boolean
112 def blank?(obj)
113 obj.respond_to?(:empty?) ? obj.empty? : !obj
114 end
115
116 # Parse JSON with symbolized names.
117 # @param json string - JSON to parse.
118 # @return hash
119 def json_parse(json)
120 JSON.parse(json, symbolize_names: true)
121 end
122
123 # Parse a URI into the desired string format
124 # @param uri - the URI to parse
125 # @return string
126 def uri_string(uri)
127 temp_domain = URI(uri)
128 temp_domain = URI("https://#{uri}") unless temp_domain.scheme
129 "#{temp_domain}/"
130 end
131 end
132 end
133 end
0 require 'json'
1
2 module OmniAuth
3 module Auth0
4 # Module to provide necessary telemetry for API requests.
5 module Telemetry
6
7 # Return a telemetry hash to be encoded and sent to Auth0.
8 # @return hash
9 def telemetry
10 telemetry = {
11 name: 'omniauth-auth0',
12 version: OmniAuth::Auth0::VERSION,
13 env: {
14 ruby: RUBY_VERSION
15 }
16 }
17 add_rails_version telemetry
18 end
19
20 # JSON-ify and base64 encode the current telemetry.
21 # @return string
22 def telemetry_encoded
23 Base64.urlsafe_encode64(JSON.dump(telemetry))
24 end
25
26 private
27
28 def add_rails_version(telemetry)
29 return telemetry unless Gem.loaded_specs['rails'].respond_to? :version
30 telemetry[:env][:rails] = Gem.loaded_specs['rails'].version.to_s
31 telemetry
32 end
33 end
34 end
35 end
0 # frozen_string_literal: true
1
02 require 'base64'
13 require 'uri'
24 require 'omniauth-oauth2'
5 require 'omniauth/auth0/jwt_validator'
6 require 'omniauth/auth0/telemetry'
37
48 module OmniAuth
59 module Strategies
610 # Auth0 OmniAuth strategy
711 class Auth0 < OmniAuth::Strategies::OAuth2
12 include OmniAuth::Auth0::Telemetry
13
814 option :name, 'auth0'
915
10 args [
11 :client_id,
12 :client_secret,
13 :domain
16 args %i[
17 client_id
18 client_secret
19 domain
1420 ]
1521
22 # Setup client URLs used during authentication
1623 def client
1724 options.client_options.site = domain_url
1825 options.client_options.authorize_url = '/authorize'
2128 super
2229 end
2330
31 # Use the "sub" key of the userinfo returned
32 # as the uid (globally unique string identifier).
2433 uid { raw_info['sub'] }
2534
35 # Build the API credentials hash with returned auth data.
2636 credentials do
27 hash = { 'token' => access_token.token }
28 hash['expires'] = true
37 credentials = {
38 'token' => access_token.token,
39 'expires' => true
40 }
41
2942 if access_token.params
30 hash['id_token'] = access_token.params['id_token']
31 hash['token_type'] = access_token.params['token_type']
32 hash['refresh_token'] = access_token.refresh_token
43 credentials.merge!(
44 'id_token' => access_token.params['id_token'],
45 'token_type' => access_token.params['token_type'],
46 'refresh_token' => access_token.refresh_token
47 )
3348 end
34 hash
49
50 # Make sure the ID token can be verified and decoded.
51 auth0_jwt = OmniAuth::Auth0::JWTValidator.new(options)
52 jwt_decoded = auth0_jwt.decode(credentials['id_token'])
53 fail!(:invalid_id_token) unless jwt_decoded.length
54
55 credentials
3556 end
3657
58 # Store all raw information for use in the session.
3759 extra do
3860 {
3961 raw_info: raw_info
4062 }
4163 end
4264
65 # Build a hash of information about the user
66 # with keys taken from the Auth Hash Schema.
4367 info do
4468 {
4569 name: raw_info['name'] || raw_info['sub'],
4973 }
5074 end
5175
76 # Define the parameters used for the /authorize endpoint
5277 def authorize_params
5378 params = super
54 params['auth0Client'] = client_info
79 parsed_query = Rack::Utils.parse_query(request.query_string)
80 params['connection'] = parsed_query['connection']
81 params['prompt'] = parsed_query['prompt']
5582 params
5683 end
5784
85 def build_access_token
86 options.token_params[:headers] = { 'Auth0-Client' => telemetry_encoded }
87 super
88 end
89
90 # Declarative override for the request phase of authentication
5891 def request_phase
5992 if no_client_id?
93 # Do we have a client_id for this Application?
6094 fail!(:missing_client_id)
6195 elsif no_client_secret?
96 # Do we have a client_secret for this Application?
6297 fail!(:missing_client_secret)
6398 elsif no_domain?
99 # Do we have a domain for this Application?
64100 fail!(:missing_domain)
65101 else
102 # All checks pass, run the Oauth2 request_phase method.
66103 super
67104 end
68105 end
69106
70107 private
71108
109 # Parse the raw user info.
72110 def raw_info
73111 userinfo_url = options.client_options.userinfo_url
74112 @raw_info ||= access_token.get(userinfo_url).parsed
75113 end
76114
115 # Check if the options include a client_id
77116 def no_client_id?
78117 ['', nil].include?(options.client_id)
79118 end
80119
120 # Check if the options include a client_secret
81121 def no_client_secret?
82122 ['', nil].include?(options.client_secret)
83123 end
84124
125 # Check if the options include a domain
85126 def no_domain?
86127 ['', nil].include?(options.domain)
87128 end
88129
130 # Normalize a domain to a URL.
89131 def domain_url
90132 domain_url = URI(options.domain)
91133 domain_url = URI("https://#{domain_url}") if domain_url.scheme.nil?
92134 domain_url.to_s
93135 end
94
95 def client_info
96 client_info = JSON.dump(
97 name: 'omniauth-auth0',
98 version: OmniAuth::Auth0::VERSION
99 )
100 Base64.urlsafe_encode64(client_info)
101 end
102136 end
103137 end
104138 end
00 module OmniAuth
11 module Auth0
2 VERSION = '2.0.0'.freeze
2 VERSION = '2.2.0'.freeze
33 end
44 end
0 require 'omniauth-auth0/version' # rubocop:disable Style/FileName
0 require 'omniauth-auth0/version'
11 require 'omniauth/strategies/auth0'
77 s.authors = ['Auth0']
88 s.email = ['info@auth0.com']
99 s.homepage = 'https://github.com/auth0/omniauth-auth0'
10 s.summary = 'Omniauth OAuth2 strategy for the Auth0 platform.'
10 s.summary = 'OmniAuth OAuth2 strategy for the Auth0 platform.'
1111 s.description = %q{Auth0 is an authentication broker that supports social identity providers as well as enterprise identity providers such as Active Directory, LDAP, Google Apps, Salesforce.
1212
1313 OmniAuth is a library that standardizes multi-provider authentication for web applications. It was created to be powerful, flexible, and do as little as possible.
1414
15 omniauth-auth0 is the omniauth strategy for Auth0.
15 omniauth-auth0 is the OmniAuth strategy for Auth0.
1616 }
1717
1818 s.rubyforge_project = 'omniauth-auth0'
2222 s.executables = `git ls-files -- bin/*`.split('\n').map{ |f| File.basename(f) }
2323 s.require_paths = ['lib']
2424
25 s.add_runtime_dependency 'omniauth-oauth2', '~> 1.4'
25 s.add_runtime_dependency 'omniauth-oauth2', '~> 1.5'
2626
2727 s.add_development_dependency 'bundler', '~> 1.9'
2828
0 require 'spec_helper'
1 require 'json'
2 require 'jwt'
3
4 describe OmniAuth::Auth0::JWTValidator do
5 #
6 # Reused data
7 #
8
9 let(:client_id) { 'CLIENT_ID' }
10 let(:client_secret) { 'CLIENT_SECRET' }
11 let(:domain) { 'samples.auth0.com' }
12 let(:future_timecode) { 32_503_680_000 }
13 let(:past_timecode) { 303_912_000 }
14 let(:jwks_kid) { 'NkJCQzIyQzRBMEU4NjhGNUU4MzU4RkY0M0ZDQzkwOUQ0Q0VGNUMwQg' }
15
16 let(:rsa_private_key) do
17 OpenSSL::PKey::RSA.generate 2048
18 end
19
20 let(:rsa_token_jwks) do
21 {
22 keys: [
23 {
24 kid: jwks_kid,
25 x5c: [Base64.encode64(make_cert(rsa_private_key).to_der)]
26 }
27 ]
28 }.to_json
29 end
30
31 let(:jwks) do
32 current_dir = File.dirname(__FILE__)
33 jwks_file = File.read("#{current_dir}/../../resources/jwks.json")
34 JSON.parse(jwks_file, symbolize_names: true)
35 end
36
37 #
38 # Specs
39 #
40
41 describe 'JWT verifier default values' do
42 let(:jwt_validator) do
43 make_jwt_validator
44 end
45
46 it 'should have the correct issuer' do
47 expect(jwt_validator.issuer).to eq('https://samples.auth0.com/')
48 end
49 end
50
51 describe 'JWT verifier token_head' do
52 let(:jwt_validator) do
53 make_jwt_validator
54 end
55
56 it 'should parse the head of a valid JWT' do
57 expect(jwt_validator.token_head(make_hs256_token)[:alg]).to eq('HS256')
58 end
59
60 it 'should fail parsing the head of a blank JWT' do
61 expect(jwt_validator.token_head('')).to eq({})
62 end
63
64 it 'should fail parsing the head of an invalid JWT' do
65 expect(jwt_validator.token_head('.')).to eq({})
66 end
67
68 it 'should throw an exception for invalid JSON' do
69 expect do
70 jwt_validator.token_head('QXV0aDA=')
71 end.to raise_error(JSON::ParserError)
72 end
73 end
74
75 describe 'JWT verifier jwks_public_cert' do
76 let(:jwt_validator) do
77 make_jwt_validator
78 end
79
80 it 'should return a public_key' do
81 x5c = jwks[:keys].first[:x5c].first
82 public_cert = jwt_validator.jwks_public_cert(x5c)
83 expect(public_cert.instance_of?(OpenSSL::PKey::RSA)).to eq(true)
84 end
85
86 it 'should fail with an invalid x5c' do
87 expect do
88 jwt_validator.jwks_public_cert('QXV0aDA=')
89 end.to raise_error(OpenSSL::X509::CertificateError)
90 end
91 end
92
93 describe 'JWT verifier jwks_key' do
94 let(:jwt_validator) do
95 make_jwt_validator
96 end
97
98 before do
99 stub_jwks
100 end
101
102 it 'should return a key' do
103 expect(jwt_validator.jwks_key(:alg, jwks_kid)).to eq('RS256')
104 end
105
106 it 'should return an x5c key' do
107 expect(jwt_validator.jwks_key(:x5c, jwks_kid).length).to eq(1)
108 end
109
110 it 'should return nil if there is not key' do
111 expect(jwt_validator.jwks_key(:auth0, jwks_kid)).to eq(nil)
112 end
113
114 it 'should return nil if the key ID is invalid' do
115 expect(jwt_validator.jwks_key(:alg, "#{jwks_kid}_invalid")).to eq(nil)
116 end
117 end
118
119 describe 'JWT verifier custom issuer' do
120 context 'same as domain' do
121 let(:jwt_validator) do
122 make_jwt_validator(opt_issuer: domain)
123 end
124
125 it 'should have the correct issuer' do
126 expect(jwt_validator.issuer).to eq('https://samples.auth0.com/')
127 end
128
129 it 'should have the correct domain' do
130 expect(jwt_validator.issuer).to eq('https://samples.auth0.com/')
131 end
132 end
133
134 context 'different from domain' do
135 let(:jwt_validator) do
136 make_jwt_validator(opt_issuer: 'different.auth0.com')
137 end
138
139 it 'should have the correct issuer' do
140 expect(jwt_validator.issuer).to eq('https://different.auth0.com/')
141 end
142
143 it 'should have the correct domain' do
144 expect(jwt_validator.domain).to eq('https://samples.auth0.com/')
145 end
146 end
147 end
148
149 describe 'JWT verifier decode' do
150 let(:jwt_validator) do
151 make_jwt_validator
152 end
153
154 before do
155 stub_jwks
156 stub_dummy_jwks
157 end
158
159 it 'should fail with passed expiration' do
160 payload = {
161 exp: past_timecode
162 }
163 token = make_hs256_token(payload)
164 expect do
165 jwt_validator.decode(token)
166 end.to raise_error(JWT::ExpiredSignature)
167 end
168
169 it 'should fail with missing issuer' do
170 expect do
171 jwt_validator.decode(make_hs256_token)
172 end.to raise_error(JWT::InvalidIssuerError)
173 end
174
175 it 'should fail with invalid issuer' do
176 payload = {
177 iss: 'https://auth0.com/'
178 }
179 token = make_hs256_token(payload)
180 expect do
181 jwt_validator.decode(token)
182 end.to raise_error(JWT::InvalidIssuerError)
183 end
184
185 it 'should fail with a future not before' do
186 payload = {
187 nbf: future_timecode,
188 iss: "https://#{domain}/"
189 }
190 token = make_hs256_token(payload)
191 expect do
192 jwt_validator.decode(token)
193 end.to raise_error(JWT::ImmatureSignature)
194 end
195
196 it 'should fail with missing audience' do
197 payload = {
198 iss: "https://#{domain}/"
199 }
200 token = make_hs256_token(payload)
201 expect do
202 jwt_validator.decode(token)
203 end.to raise_error(JWT::InvalidAudError)
204 end
205
206 it 'should fail with invalid audience' do
207 payload = {
208 iss: "https://#{domain}/",
209 aud: 'Auth0'
210 }
211 token = make_hs256_token(payload)
212 expect do
213 jwt_validator.decode(token)
214 end.to raise_error(JWT::InvalidAudError)
215 end
216
217 it 'should decode a valid HS256 token with multiple audiences' do
218 payload = {
219 iss: "https://#{domain}/",
220 aud: [
221 client_id,
222 "https://#{domain}/userinfo"
223 ]
224 }
225 token = make_hs256_token(payload)
226 expect(jwt_validator.decode(token).length).to eq(2)
227 end
228
229 it 'should decode a standard HS256 token' do
230 sub = 'abc123'
231 payload = {
232 sub: sub,
233 exp: future_timecode,
234 iss: "https://#{domain}/",
235 iat: past_timecode,
236 aud: client_id
237 }
238 token = make_hs256_token(payload)
239 decoded_token = jwt_validator.decode(token)
240 expect(decoded_token.first['sub']).to eq(sub)
241 end
242
243 it 'should decode a standard RS256 token' do
244 domain = 'example.org'
245 sub = 'abc123'
246 payload = {
247 sub: sub,
248 exp: future_timecode,
249 iss: "https://#{domain}/",
250 iat: past_timecode,
251 aud: client_id,
252 kid: jwks_kid
253 }
254 token = make_rs256_token(payload)
255 decoded_token = make_jwt_validator(opt_domain: domain).decode(token)
256 expect(decoded_token.first['sub']).to eq(sub)
257 end
258 end
259
260 private
261
262 def make_jwt_validator(opt_domain: domain, opt_issuer: nil)
263 opts = OpenStruct.new(
264 domain: opt_domain,
265 client_id: client_id,
266 client_secret: client_secret
267 )
268 opts[:issuer] = opt_issuer unless opt_issuer.nil?
269
270 OmniAuth::Auth0::JWTValidator.new(opts)
271 end
272
273 def make_hs256_token(payload = nil)
274 payload = { sub: 'abc123' } if payload.nil?
275 JWT.encode payload, client_secret, 'HS256'
276 end
277
278 def make_rs256_token(payload = nil)
279 payload = { sub: 'abc123' } if payload.nil?
280 JWT.encode payload, rsa_private_key, 'RS256', kid: jwks_kid
281 end
282
283 def make_cert(private_key)
284 cert = OpenSSL::X509::Certificate.new
285 cert.issuer = OpenSSL::X509::Name.parse('/C=BE/O=Auth0/OU=Auth0/CN=Auth0')
286 cert.subject = cert.issuer
287 cert.not_before = Time.now
288 cert.not_after = Time.now + 365 * 24 * 60 * 60
289 cert.public_key = private_key.public_key
290 cert.serial = 0x0
291 cert.version = 2
292
293 ef = OpenSSL::X509::ExtensionFactory.new
294 ef.subject_certificate = cert
295 ef.issuer_certificate = cert
296 cert.extensions = [
297 ef.create_extension('basicConstraints', 'CA:TRUE', true),
298 ef.create_extension('subjectKeyIdentifier', 'hash')
299 ]
300 cert.add_extension ef.create_extension(
301 'authorityKeyIdentifier',
302 'keyid:always,issuer:always'
303 )
304
305 cert.sign private_key, OpenSSL::Digest::SHA1.new
306 end
307
308 def stub_jwks
309 stub_request(:get, 'https://samples.auth0.com/.well-known/jwks.json')
310 .to_return(
311 headers: { 'Content-Type' => 'application/json' },
312 body: jwks.to_json,
313 status: 200
314 )
315 end
316
317 def stub_bad_jwks
318 stub_request(:get, 'https://samples.auth0.com/.well-known/jwks-bad.json')
319 .to_return(
320 status: 404
321 )
322 end
323
324 def stub_dummy_jwks
325 stub_request(:get, 'https://example.org/.well-known/jwks.json')
326 .to_return(
327 headers: { 'Content-Type' => 'application/json' },
328 body: rsa_token_jwks,
329 status: 200
330 )
331 end
332 end
0 require 'spec_helper'
1 require 'json'
2
3 describe OmniAuth::Auth0::Telemetry do
4
5 let(:test_class) { Class.new.extend(OmniAuth::Auth0::Telemetry) }
6
7 describe 'telemetry' do
8
9 it 'should have the correct SDK name' do
10 expect(test_class.telemetry).to have_key(:name)
11 expect(test_class.telemetry[:name]).to eq('omniauth-auth0')
12 end
13
14 it 'should have the correct SDK version' do
15 expect(test_class.telemetry).to have_key(:version)
16 expect(test_class.telemetry[:version]).to eq(OmniAuth::Auth0::VERSION)
17 end
18
19 it 'should include the Ruby version' do
20 expect(test_class.telemetry).to have_key(:env)
21 expect(test_class.telemetry[:env]).to have_key(:ruby)
22 expect(test_class.telemetry[:env][:ruby]).to eq(RUBY_VERSION)
23 end
24
25 end
26
27 end
0 # frozen_string_literal: true
1
02 require 'spec_helper'
3 require 'jwt'
14
25 RSpec.shared_examples 'site has valid domain url' do |url|
36 it { expect(subject.site).to eq(url) }
7780 expect(redirect_url).to have_query('state')
7881 expect(redirect_url).to have_query('client_id')
7982 expect(redirect_url).to have_query('redirect_uri')
83 expect(redirect_url).not_to have_query('auth0Client')
84 end
85
86 it 'redirects to hosted login page' do
87 get 'auth/auth0?connection=abcd'
88 expect(last_response.status).to eq(302)
89 redirect_url = last_response.headers['Location']
90 expect(redirect_url).to start_with('https://samples.auth0.com/authorize')
91 expect(redirect_url).to have_query('response_type', 'code')
92 expect(redirect_url).to have_query('state')
93 expect(redirect_url).to have_query('client_id')
94 expect(redirect_url).to have_query('redirect_uri')
95 expect(redirect_url).to have_query('connection', 'abcd')
96 expect(redirect_url).not_to have_query('auth0Client')
8097 end
8198
8299 describe 'callback' do
84101 let(:expires_in) { 2000 }
85102 let(:token_type) { 'bearer' }
86103 let(:refresh_token) { 'refresh token' }
87 let(:id_token) { 'id token' }
104 let(:telemetry_value) { Class.new.extend(OmniAuth::Auth0::Telemetry).telemetry_encoded }
88105
89106 let(:user_id) { 'user identifier' }
90107 let(:state) { SecureRandom.hex(8) }
94111 let(:email) { 'mail@mail.com' }
95112 let(:email_verified) { true }
96113
114 let(:id_token) do
115 payload = {}
116 payload['sub'] = user_id
117 payload['iss'] = "#{domain_url}/"
118 payload['aud'] = client_id
119 JWT.encode payload, client_secret, 'HS256'
120 end
121
97122 let(:oauth_response) do
98123 {
124 id_token: id_token,
99125 access_token: access_token,
100126 expires_in: expires_in,
101127 token_type: token_type
125151
126152 def stub_auth(body)
127153 stub_request(:post, 'https://samples.auth0.com/oauth/token')
154 .with(headers: { 'Auth0-Client' => telemetry_value })
128155 .to_return(
129156 headers: { 'Content-Type' => 'application/json' },
130157 body: MultiJson.encode(body)
0 {
1 "keys": [
2 {
3 "alg": "RS256",
4 "kty": "RSA",
5 "use": "sig",
6 "x5c": [
7 "MIIDCzCCAfOgAwIBAgIJAJP6qydiMpsuMA0GCSqGSIb3DQEBBQUAMBwxGjAYBgNVBAMMEXNhbXBsZXMuYXV0aDAuY29tMB4XDTE0MDUyNjIyMDA1MFoXDTI4MDIwMjIyMDA1MFowHDEaMBgGA1UEAwwRc2FtcGxlcy5hdXRoMC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCkH4CFGSJ4s3mwCBzaGGwxa9Jxzfb1ia4nUumxbsuaB7PClZZgrNQiOR3MXVNV9W6F1D+wjT6oFHOo7TOkVI22I/ff3XZTE0F35UUHGWRtiQ4LdZxwOPTed2Lax3F2DEyl3Y0CguUKbq2sSghvHYcggM6aj3N53VBsnBh/kdrURDLx1RYqBIL6Fvkhb/V/v/u9UKhZM0CDQRef9FZ7R8q9ie9cnbDOj1dT9d64kiJIYtTraG0gOrs4LI+4KK0EZu5R7Uo053IK7kfNasWhDkl8yxNYkDxwfcIuAcDmLgLnAI4tfW5beJuw+/w75PO/EwzwsnvppXaAz7e3Wf8g1yWFAgMBAAGjUDBOMB0GA1UdDgQWBBTsmytFLNox+NUZdTNlCUL3hHrngTAfBgNVHSMEGDAWgBTsmytFLNox+NUZdTNlCUL3hHrngTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAodbRX/34LnWB70l8dpDF1neDoG29F0XdpE9ICWHeWB1gb/FvJ5UMy9/pnL0DI3mPwkTDDob+16Zc68o6dT6sH3vEUP1iRreJlFADEmJZjrH9P4Y7ttx3G2Uw2RU5uucXIqiyMDBrQo4vx4Lnghl+b/WYbZJgzLfZLgkOEjcznS0Yi5Wdz6MvaL3FehSfweHyrjmxz0e8elHq7VY8OqRA+4PmUBce9BgDCk9fZFjgj8l0m9Vc5pPKSY9LMmTyrYkeDr/KppqdXKOCHmv7AIGb6rMCtbkIL/CM7Bh9Hx78/UKAz87Sl9A1yXVNjKbZwOEW60ORIwJmd8Tv46gJF+/rV"
8 ],
9 "n": "pB-AhRkieLN5sAgc2hhsMWvScc329YmuJ1LpsW7LmgezwpWWYKzUIjkdzF1TVfVuhdQ_sI0-qBRzqO0zpFSNtiP33912UxNBd-VFBxlkbYkOC3WccDj03ndi2sdxdgxMpd2NAoLlCm6trEoIbx2HIIDOmo9zed1QbJwYf5Ha1EQy8dUWKgSC-hb5IW_1f7_7vVCoWTNAg0EXn_RWe0fKvYnvXJ2wzo9XU_XeuJIiSGLU62htIDq7OCyPuCitBGbuUe1KNOdyCu5HzWrFoQ5JfMsTWJA8cH3CLgHA5i4C5wCOLX1uW3ibsPv8O-TzvxMM8LJ76aV2gM-3t1n_INclhQ",
10 "e": "AQAB",
11 "kid": "NkJCQzIyQzRBMEU4NjhGNUU4MzU4RkY0M0ZDQzkwOUQ0Q0VGNUMwQg",
12 "x5t": "NkJCQzIyQzRBMEU4NjhGNUU4MzU4RkY0M0ZDQzkwOUQ0Q0VGNUMwQg"
13 },
14 {
15 "alg": "RS256",
16 "kty": "RSA",
17 "use": "sig",
18 "x5c": [
19 "MIIC8DCCAdigAwIBAgIJ4pL5sRgcIYGZMA0GCSqGSIb3DQEBBQUAMB8xHTAbBgNVBAMTFGxiYWxtYWNlZGEuYXV0aDAuY29tMB4XDTE1MTIxMjE5MDczM1oXDTI5MDgyMDE5MDczM1owHzEdMBsGA1UEAxMUbGJhbG1hY2VkYS5hdXRoMC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPoo5DA/X8suAZujdmD2D88Ggtu8G/kuLUdEuj1W3+wzmFcEqQpE532rg8L0uppWKAbmLWzkuwyioNDhWwCtXnug3BFQf5Lrc6nTxjk4ZQt/HdsYWCGSSZueMUG/3I+2PSql3atD2nedjY6Z9hWU8kzOjF9wzkLMgPf/OYpuz9A+6d+/K8jApRPfsQ1LDVWDG8YRtj+IyHhSvXS+cK03iuD7yVLKkIZuoS8ymMJpnZONHGds/3P9pHY29KqliSYW0eGEX3BIarZG06gRJ+88WUbRi9+rfVAoGLq++S+bc021txK+qYS3nknhY0uv/ODBb4eeycuDjjdyLBCShVvbXFAgMBAAGjLzAtMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFG38TTjyzhRmpK7MXfvBXDcBtYJ3MA0GCSqGSIb3DQEBBQUAA4IBAQCLNW+rA25tjHs6Sa9VPgBfMMLd1PIEgMpQhET9JqpGYUgB+0q1leXw1cwh14x/6PF2oo3jPOMW+wCDA7KAVKYewYSr/Enph+zNFPaq2YQL9dCsVFcBsnEGznwZaqHrqxQDX9S2Ek6E9jNsuBCSpAPcTsfbn2TXz77V+HZ/4tbwRvYEX1S5agiZFyjZzJMiZU1KQzP5PhfzD6RPl5KTK2PYRhVdXwyuFxOdJzCzOC9E/Uw30Zd6+9oHmoNfvJr8BRy67YWjXaQAh2m8e+zv/dEzPimgvaLmI1yz4W+93dJy3NdMuCvObOqA534tviv5PkV57ewXAnWPbxyBHr57HdQ1"
20 ],
21 "n": "z6KOQwP1_LLgGbo3Zg9g_PBoLbvBv5Li1HRLo9Vt_sM5hXBKkKROd9q4PC9LqaVigG5i1s5LsMoqDQ4VsArV57oNwRUH-S63Op08Y5OGULfx3bGFghkkmbnjFBv9yPtj0qpd2rQ9p3nY2OmfYVlPJMzoxfcM5CzID3_zmKbs_QPunfvyvIwKUT37ENSw1VgxvGEbY_iMh4Ur10vnCtN4rg-8lSypCGbqEvMpjCaZ2TjRxnbP9z_aR2NvSqpYkmFtHhhF9wSGq2RtOoESfvPFlG0Yvfq31QKBi6vvkvm3NNtbcSvqmEt55J4WNLr_zgwW-HnsnLg443ciwQkoVb21xQ",
22 "e": "AQAB",
23 "kid": "RUVBOTVEMEZBMTA5NDAzNEQzNTZGNzMyMTI4MzU1RkNFQzhCQTM0Mg",
24 "x5t": "RUVBOTVEMEZBMTA5NDAzNEQzNTZGNzMyMTI4MzU1RkNFQzhCQTM0Mg"
25 }
26 ]
27 }
0 $LOAD_PATH.unshift File.expand_path('..', __FILE__)
1 $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
0 $LOAD_PATH.unshift File.expand_path(__dir__)
1 $LOAD_PATH.unshift File.expand_path('../lib', __dir__)
22
33 require 'simplecov'
4 if ENV['COVERAGE']
5 SimpleCov.start do
6 minimum_coverage(89.8)
7 end
4 SimpleCov.start
5
6 if ENV['CI'] == 'true'
7 require 'codecov'
8 SimpleCov.formatter = SimpleCov::Formatter::Codecov
89 end
10
911 require 'rspec'
1012 require 'rack/test'
1113 require 'webmock/rspec'