omniauth-azure-activedirectory-davevanfleet 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.rubocop.yml +8 -0
  4. data/.rubocop_todo.yml +20 -0
  5. data/.travis.yml +7 -0
  6. data/Gemfile +3 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +86 -0
  9. data/RELEASES.md +48 -0
  10. data/Rakefile +22 -0
  11. data/examples/rails-todo-list-app/.gitignore +25 -0
  12. data/examples/rails-todo-list-app/Gemfile +33 -0
  13. data/examples/rails-todo-list-app/README.md +83 -0
  14. data/examples/rails-todo-list-app/Rakefile +3 -0
  15. data/examples/rails-todo-list-app/app/assets/javascripts/application.js +4 -0
  16. data/examples/rails-todo-list-app/app/assets/stylesheets/application.css +2 -0
  17. data/examples/rails-todo-list-app/app/controllers/application_controller.rb +3 -0
  18. data/examples/rails-todo-list-app/app/controllers/home_controller.rb +2 -0
  19. data/examples/rails-todo-list-app/app/controllers/profile_controller.rb +20 -0
  20. data/examples/rails-todo-list-app/app/controllers/sessions_controller.rb +28 -0
  21. data/examples/rails-todo-list-app/app/controllers/signed_in_controller.rb +25 -0
  22. data/examples/rails-todo-list-app/app/controllers/tasks_controller.rb +33 -0
  23. data/examples/rails-todo-list-app/app/models/task.rb +10 -0
  24. data/examples/rails-todo-list-app/app/models/user.rb +58 -0
  25. data/examples/rails-todo-list-app/app/views/home/index.html.haml +4 -0
  26. data/examples/rails-todo-list-app/app/views/layouts/application.html.haml +12 -0
  27. data/examples/rails-todo-list-app/app/views/layouts/signed_in.html.haml +18 -0
  28. data/examples/rails-todo-list-app/app/views/profile/index.html.haml +13 -0
  29. data/examples/rails-todo-list-app/app/views/tasks/index.html.haml +11 -0
  30. data/examples/rails-todo-list-app/bin/bundle +3 -0
  31. data/examples/rails-todo-list-app/bin/rails +4 -0
  32. data/examples/rails-todo-list-app/bin/rake +4 -0
  33. data/examples/rails-todo-list-app/bin/setup +29 -0
  34. data/examples/rails-todo-list-app/config.ru +4 -0
  35. data/examples/rails-todo-list-app/config/application.rb +29 -0
  36. data/examples/rails-todo-list-app/config/boot.rb +3 -0
  37. data/examples/rails-todo-list-app/config/database.yml +25 -0
  38. data/examples/rails-todo-list-app/config/environment.rb +13 -0
  39. data/examples/rails-todo-list-app/config/environments/development.rb +41 -0
  40. data/examples/rails-todo-list-app/config/environments/production.rb +79 -0
  41. data/examples/rails-todo-list-app/config/environments/test.rb +42 -0
  42. data/examples/rails-todo-list-app/config/initializers/assets.rb +11 -0
  43. data/examples/rails-todo-list-app/config/initializers/backtrace_silencers.rb +7 -0
  44. data/examples/rails-todo-list-app/config/initializers/cookies_serializer.rb +3 -0
  45. data/examples/rails-todo-list-app/config/initializers/filter_parameter_logging.rb +4 -0
  46. data/examples/rails-todo-list-app/config/initializers/inflections.rb +16 -0
  47. data/examples/rails-todo-list-app/config/initializers/mime_types.rb +4 -0
  48. data/examples/rails-todo-list-app/config/initializers/omniauth.rb +3 -0
  49. data/examples/rails-todo-list-app/config/initializers/session_store.rb +3 -0
  50. data/examples/rails-todo-list-app/config/initializers/wrap_parameters.rb +14 -0
  51. data/examples/rails-todo-list-app/config/routes.rb +22 -0
  52. data/examples/rails-todo-list-app/db/schema.rb +35 -0
  53. data/examples/rails-todo-list-app/public/404.html +67 -0
  54. data/examples/rails-todo-list-app/public/422.html +67 -0
  55. data/examples/rails-todo-list-app/public/500.html +66 -0
  56. data/examples/rails-todo-list-app/public/favicon.ico +0 -0
  57. data/examples/sinatra-multiple-providers-app/.env +11 -0
  58. data/examples/sinatra-multiple-providers-app/Gemfile +8 -0
  59. data/examples/sinatra-multiple-providers-app/README.md +13 -0
  60. data/examples/sinatra-multiple-providers-app/app.rb +51 -0
  61. data/examples/sinatra-multiple-providers-app/config.ru +45 -0
  62. data/lib/omniauth-azure-activedirectory-davevanfleet.rb +23 -0
  63. data/lib/omniauth/azure_activedirectory_davevanfleet.rb +24 -0
  64. data/lib/omniauth/azure_activedirectory_davevanfleet/version.rb +28 -0
  65. data/lib/omniauth/strategies/azure_activedirectory_davevanfleet.rb +329 -0
  66. data/omniauth-azure-activedirectory-davevanfleet.gemspec +29 -0
  67. data/spec/fixtures/id_token.txt +1 -0
  68. data/spec/fixtures/id_token_bad_audience.txt +1 -0
  69. data/spec/fixtures/id_token_bad_chash.txt +1 -0
  70. data/spec/fixtures/id_token_bad_issuer.txt +1 -0
  71. data/spec/fixtures/id_token_bad_kid.txt +1 -0
  72. data/spec/fixtures/id_token_bad_nonce.txt +1 -0
  73. data/spec/fixtures/id_token_no_alg.txt +1 -0
  74. data/spec/fixtures/x5c.txt +1 -0
  75. data/spec/fixtures/x5c_different.txt +1 -0
  76. data/spec/omniauth/strategies/azure_activedirectory_davevanfleet_spec.rb +222 -0
  77. data/spec/spec_helper.rb +44 -0
  78. metadata +245 -0
@@ -0,0 +1,29 @@
1
+ $LOAD_PATH.push File.expand_path('../lib', __FILE__)
2
+ require 'omniauth/azure_activedirectory_davevanfleet/version'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'omniauth-azure-activedirectory-davevanfleet'
6
+ s.version = OmniAuth::AzureActiveDirectoryDavevanfleet::VERSION
7
+ s.author = 'Microsoft Corporation'
8
+ s.email = 'nugetaad@microsoft.com'
9
+ s.summary = 'Azure Active Directory strategy for OmniAuth'
10
+ s.description = 'Allows developers to authenticate to AAD'
11
+ s.homepage = 'https://github.com/AzureAD/omniauth-azure-activedirectory'
12
+ s.license = 'MIT'
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ s.require_paths = ['lib']
16
+
17
+ s.required_ruby_version = '>= 2.2'
18
+
19
+ s.add_runtime_dependency 'jwt', '>= 2.0'
20
+ s.add_runtime_dependency 'oauth2', '~> 1.1'
21
+ s.add_runtime_dependency 'omniauth', '~> 2.0'
22
+ s.add_runtime_dependency 'omniauth-oauth2', '~> 1.7.1'
23
+
24
+ s.add_development_dependency 'rake', '~> 12.0'
25
+ s.add_development_dependency 'rspec', '~> 3.6'
26
+ s.add_development_dependency 'rubocop', '~> 0.49'
27
+ s.add_development_dependency 'simplecov', '~> 0.10'
28
+ s.add_development_dependency 'webmock', '~> 1.21'
29
+ end
@@ -0,0 +1 @@
1
+ eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImFiYzEyMyJ9.eyJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9idW5jaC1vZi1yYW5kb20tY2hhcnMiLCJuYW1lIjoiSm9obiBTbWl0aCIsImF1ZCI6InRoZSBjbGllbnQgaWQiLCJub25jZSI6Im15IG5vbmNlIiwiZ2l2ZW5fbmFtZSI6IkpvaG4iLCJmYW1pbHlfbmFtZSI6InNtaXRoIiwiZW1haWwiOiJqc21pdGhAY29udG9zby5jb20iLCJjX2hhc2giOiJWcFRRaWk1VF84cmd3eEEtV3RiMkJ3In0.Xz9SL1dm9xeJ3YtBIwSpL7SHEMr5lsL32mkJIugoAt7rNhj2ZauN77_N3skU9FIRTVb_XBFHrLo1AXion7RWoOGAMk8xnuQRlhamGoWsjttWE9oO6J6kuQPSDBvLTA88UqLoGNezDwFNfgUFQq-66m33ZWdkiNOFoFZ_In6DtAwxHZZUys-KoYD3iCbviUoBzU57aV-SBsWyComq39pDGpw03qZoa_xgRfujdVHG1DKlO5VG79kUE3ySYWJyBYVKUdAzjH1iotjpPA1svtqytn4CUldAMi4nnf7iq5SCJMb4ucu0mN6AhJH9ktY--fGY6_OidyiDe4F57ZzLw-3jOQ
@@ -0,0 +1 @@
1
+ eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImFiYzEyMyJ9.eyJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9idW5jaC1vZi1yYW5kb20tY2hhcnMiLCJuYW1lIjoiSm9obiBTbWl0aCIsImF1ZCI6Im5vdCB0aGUgY2xpZW50IGlkIiwibm9uY2UiOiJteSBub25jZSIsImdpdmVuX25hbWUiOiJKb2huIiwiZmFtaWx5X25hbWUiOiJzbWl0aCIsImVtYWlsIjoianNtaXRoQGNvbnRvc28uY29tIn0.gGCFTcGDBb2P5tPRj2ojUUiwOJoSslQlxEVTElZY6FCzCZzcypsnrYOB9Adkztp2AWF4wW9fT58lqXwaahKquXtK4wyK4KoNBxXBhS4sDMeNpVkK4914tT_6gecvyUsI_tlJaS0epd5c0mN9-1QjgvNEirY1L-XYaT290LmLYVYIFTEJXoSlnwvv081k0txdJZKr14JXd_bSLUbhGSd-NcGZkJuVmg2F_C65zd1wUsQOkV2iVdJ-ycaDJklv8-DFfDFIHQio8S9yqyieHwArRmTW9HzcoHhWBh2MIItszoTSbmQEF062NtNBPW8gyk1OSot5X9klJUhgPAAFqJ0TJQ
@@ -0,0 +1 @@
1
+ eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImFiYzEyMyJ9.eyJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9idW5jaC1vZi1yYW5kb20tY2hhcnMiLCJuYW1lIjoiSm9obiBTbWl0aCIsImF1ZCI6InRoZSBjbGllbnQgaWQiLCJub25jZSI6Im15IG5vbmNlIiwiZ2l2ZW5fbmFtZSI6IkpvaG4iLCJmYW1pbHlfbmFtZSI6InNtaXRoIiwiZW1haWwiOiJqc21pdGhAY29udG9zby5jb20iLCJjX2hhc2giOiI1WEhDdk9qcUgtbnJBXzNXNUJYaWJnIn0.EHPFrxMbr2EH1IZ15F3oP1yvrukadY4ggZSOxm625qPoMxfhv-QzFm0YMhkAG0cLM_LSHi_RgedDwTGuzOtIWqmheYzydnhtbIBeKmx0RSgdob6WeiTZwJ93VRiV4q82Qda41JaaIl_wdWd4lVyVstd9o9jPYMtKEVLgaNDrtHt6pPxEGCVraiaM6tVyKc5XIHu3wNaqle5UZZREU6oirwTCUhXDZkz1g5qY2-aWUdfFVsElSarJuMcxGDPD20hvx7T3D7SCHAF8WhKw3AwQyrodKWCo3cqDOz6vHymb_-ELkJc14GMbtJiyrf6XYySZZoseoI_WBDmLfKcK637xCw
@@ -0,0 +1 @@
1
+ eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImFiYzEyMyJ9.eyJpc3MiOiJodHRwczovL3N0cy5pbXBvc3Rlci5uZXQvYnVuY2gtb2YtcmFuZG9tLWNoYXJzIiwibmFtZSI6IkpvaG4gU21pdGgiLCJhdWQiOiJ0aGUgY2xpZW50IGlkIiwibm9uY2UiOiJteSBub25jZSIsImdpdmVuX25hbWUiOiJKb2huIiwiZmFtaWx5X25hbWUiOiJzbWl0aCIsImVtYWlsIjoianNtaXRoQGNvbnRvc28uY29tIn0.fwnJuRsif_Td3MfXoyADHidYJyPFdWSBBoLbVAu4Lz3-pmSln9Vgxl5KowqEKq2LX5n0aqyWVGLcoT-_G_PNXuizuNmssv5vreKLvDMpsFXt2irdwGYDCRki7KQPBk3bn12YjBzE2EqiRy7dTEG_0vWoh1RqoNP72BBL8xYQUlIOFleZhT5KGNYbh7rvcmDq7aA-xdaXT3QJfHCHpitW_zVzZ5Gok_awcdx_v3r3eFbG2IT0PfmT40Ljia0aP2i60KgsOLLHarYO51KFNDEfr1pUDf4IweaEzstbVLwk-_5ulJ5QgByhNJrmWDfrGeCQRk0SO2XX-EUsVn5ySVJ5CQ
@@ -0,0 +1 @@
1
+ eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImFiYzEyMzQifQ.eyJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9idW5jaC1vZi1yYW5kb20tY2hhcnMiLCJuYW1lIjoiSm9obiBTbWl0aCIsImF1ZCI6InRoZSBjbGllbnQgaWQiLCJub25jZSI6Im15IG5vbmNlIiwiZ2l2ZW5fbmFtZSI6IkpvaG4iLCJmYW1pbHlfbmFtZSI6InNtaXRoIiwiZW1haWwiOiJqc21pdGhAY29udG9zby5jb20iLCJjX2hhc2giOiI1WEhDdk9qcUgtbnJBXzNXNUJYaWJnIn0.gWGBc9rH30SN17Ikm1CjqIYAyzFHX0yeRQu85sVYLE3r5k26bjS3R6rTJcCQlYqHPRdoPcnkUgT1QVbdThw34ICrODoavs7I5QYEn_jKP9zM4UJEKQaCLBAtitzrk1KDEf0GLcNKif-MYu7MiQfoOzwCGWfIs-vgqk4lv0JUs9OlSLp5LHru7G3jKy6Qswbrpxpjzm9I8BnKEdhUfhz4P6wIf9KLMmhgeGQdQ6wBuxPmOf9r6EKIij2AENhFp1qP90m8kXq9tIt5FZFjwIs_G6spLl0gQXyx0qC8rP5JTkqwrBUieWU-BRqVdax8YxA0iDKzZyfsMV92yVcZT6S_NQ
@@ -0,0 +1 @@
1
+ eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImFiYzEyMyJ9.eyJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9idW5jaC1vZi1yYW5kb20tY2hhcnMiLCJuYW1lIjoiSm9obiBTbWl0aCIsImF1ZCI6InRoZSBjbGllbnQgaWQiLCJub25jZSI6Im5vdCBteSBub25jZSIsImdpdmVuX25hbWUiOiJKb2huIiwiZmFtaWx5X25hbWUiOiJzbWl0aCIsImVtYWlsIjoianNtaXRoQGNvbnRvc28uY29tIn0.KBSOCiy0sUF33akept9nPNFgmMWxiPWDBVA0dZqQaF6gQkhQu82irAQzB2Ygkh9KDeIEf0MSZWLDq0X3W3Fke4wzjrbzL-2QM4l-KgPFbJixqtJYHSPOidHSCQ8vA0v8kES3H_zqU6QisygwwXLh2ozqKXMnsrBPIAtiZz_a0vPbHtrYbb-WIrtTruMemcTt5OkbfDIttzi5EarakQg93vraIb0jK0szuAqLkXFOzcIIGPgyAvVpHZveqm99GR04tbKyTRIyJP1vZwtIpu89PKFM3soWcWd_kjAWcS81ZTzEn5_P-1QL7YTInK53acNXZHh08Fba3Um4J_KlV2KRjw
@@ -0,0 +1 @@
1
+ eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImFiYzEyMyJ9.eyJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9idW5jaC1vZi1yYW5kb20tY2hhcnMiLCJuYW1lIjoiSm9obiBTbWl0aCIsImF1ZCI6InRoZSBjbGllbnQgaWQiLCJub25jZSI6Im15IG5vbmNlIiwiZ2l2ZW5fbmFtZSI6IkpvaG4iLCJmYW1pbHlfbmFtZSI6InNtaXRoIiwiZW1haWwiOiJqc21pdGhAY29udG9zby5jb20iLCJjX2hhc2giOiJWcFRRaWk1VF84cmd3eEEtV3RiMkJ3In0.Xz9SL1dm9xeJ3YtBIwSpL7SHEMr5lsL32mkJIugoAt7rNhj2ZauN77_N3skU9FIRTVb_XBFHrLo1AXion7RWoOGAMk8xnuQRlhamGoWsjttWE9oO6J6kuQPSDBvLTA88UqLoGNezDwFNfgUFQq-66m33ZWdkiNOFoFZ_In6DtAwxHZZUys-KoYD3iCbviUoBzU57aV-SBsWyComq39pDGpw03qZoa_xgRfujdVHG1DKlO5VG79kUE3ySYWJyBYVKUdAzjH1iotjpPA1svtqytn4CUldAMi4nnf7iq5SCJMb4ucu0mN6AhJH9ktY--fGY6_OidyiDe4F57ZzLw-3jOQ
@@ -0,0 +1 @@
1
+ MIIBwzCCAbegAwIBAgIBATADBgEAMDAxEzARBgoJkiaJk_IsZAEZFgNvcmcxGTAXBgoJkiaJk_IsZAEZFglydWJ5LWxhbmcwHhcNMTUwODA2MjMyOTE4WhcNMjUwODAzMjMyOTE4WjAwMRMwEQYKCZImiZPyLGQBGRYDb3JnMRkwFwYKCZImiZPyLGQBGRYJcnVieS1sYW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxyunSConbK4z1T47vukPa0OaNcY_R6l8Z0TILR1w5O_YkMbJGRXpZORFPVs83xLoxs7RcPWnibQhQ4G6m6fwEA4rutvOm-3xWyey-OOZdVqpNmxqd2VcCCI6AoUtl8m4w0UFuu-oiELj7BF8cGS5wvHYATEBEY72n_84uu-LF423Ffe8HeMEY00nO3ZVcV9MjFBVps8RAwL62ooXPZyly6fQt4728wlZPs3EMijS-Bj4auokx6ssBooaF9XiZJKKCAe16epbBB9S4XVlNXo6EhZ-PBpMFRJknDwWFFYPVOX3NlBp8chi8VaXmDXqsFJiwkkeIqg4I6WFAM4BsnDInwIDAQABMAMGAQADAQA
@@ -0,0 +1 @@
1
+ MIIBjTCCAYGgAwIBAgIBATADBgEAMBUxEzARBgoJkiaJk_IsZAEZFgNvcmcwHhcNMTUwODA3MjAyMDU1WhcNMjUwODA0MjAyMDU1WjAVMRMwEQYKCZImiZPyLGQBGRYDb3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy8VyE4KHx0GDV6RMYqscBR56lal9uQNYXm_Du8O6-F8Da9Xc0h7O8JWomqFLUEE-0ogMcjzOAiQzTc8X6VhkIBbMCKYA6OQ-hiC3aaYFLNAnxaVThnUJWXxA7spbnKFG1xZK01G8bAx7s7DbbWMHlchebjWprCMkYEjnECXVuDyfkZW-8aHDCtq62JAd-WQL1LN-UkOBCgodTNW2x7e-_KBvPzPSSzYygAh7kCl727QeHwplgA83mQrdecNvYoiEBYOjSKz8bdiKRYjmogGoDv3_W4cY76a9XBZpSoNjBWdWo_w7ce4KbOsi3V0g8EZm9ccKjBPKe9pZYF4aCNQJ6QIDAQABMAMGAQADAQA
@@ -0,0 +1,222 @@
1
+ #-------------------------------------------------------------------------------
2
+ # Copyright (c) 2015 Micorosft Corporation
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #-------------------------------------------------------------------------------
22
+
23
+ require 'spec_helper'
24
+ require 'omniauth-azure-activedirectory-davevanfleet'
25
+
26
+ # This was fairly awkward to test. I've stubbed every endpoint and am simulating
27
+ # the state of the request. Especially large strings are stored in fixtures.
28
+ describe OmniAuth::Strategies::AzureActiveDirectoryDavevanfleet do
29
+ let(:app) { -> _ { [200, {}, ['Hello world.']] } }
30
+ let(:x5c) { File.read(File.expand_path('../../../fixtures/x5c.txt', __FILE__)) }
31
+
32
+ # These values were used to create the "successful" id_token JWT.
33
+ let(:client_id) { 'the client id' }
34
+ let(:code) { 'code' }
35
+ let(:email) { 'jsmith@contoso.com' }
36
+ let(:family_name) { 'smith' }
37
+ let(:given_name) { 'John' }
38
+ let(:issuer) { 'https://sts.windows.net/bunch-of-random-chars' }
39
+ let(:kid) { 'abc123' }
40
+ let(:name) { 'John Smith' }
41
+ let(:nonce) { 'my nonce' }
42
+ let(:session_state) { 'session state' }
43
+ let(:auth_endpoint_host) { 'authorize.com' }
44
+
45
+ let(:hybrid_flow_params) do
46
+ { 'id_token' => id_token,
47
+ 'session_state' => session_state,
48
+ 'code' => code }
49
+ end
50
+
51
+ let(:tenant) { 'tenant' }
52
+ let(:openid_config_response) { "{\"issuer\":\"#{issuer}\",\"authorization_endpoint\":\"http://#{auth_endpoint_host}\",\"jwks_uri\":\"https://login.windows.net/common/discovery/keys\"}" }
53
+ let(:keys_response) { "{\"keys\":[{\"kid\":\"#{kid}\",\"x5c\":[\"#{x5c}\"]}]}" }
54
+
55
+ let(:env) { { 'rack.session' => { 'omniauth-azure-activedirectory.nonce' => nonce } } }
56
+
57
+ before(:each) do
58
+ stub_request(:get, "https://login.windows.net/#{tenant}/.well-known/openid-configuration")
59
+ .to_return(status: 200, body: openid_config_response)
60
+ stub_request(:get, 'https://login.windows.net/common/discovery/keys')
61
+ .to_return(status: 200, body: keys_response)
62
+ end
63
+
64
+ describe '#callback_phase' do
65
+ let(:request) { double('Request', params: hybrid_flow_params, path_info: 'path') }
66
+ let(:strategy) do
67
+ described_class.new(app, client_id, tenant).tap do |s|
68
+ allow(s).to receive(:request) { request }
69
+ end
70
+ end
71
+
72
+ subject { -> { strategy.callback_phase } }
73
+ before(:each) { strategy.call!(env) }
74
+
75
+ context 'with a successful response' do
76
+ # payload:
77
+ # { 'iss' => 'https://sts.windows.net/bunch-of-random-chars',
78
+ # 'name' => 'John Smith',
79
+ # 'aud' => 'the client id',
80
+ # 'nonce' => 'my nonce',
81
+ # 'email' => 'jsmith@contoso.com',
82
+ # 'given_name' => 'John',
83
+ # 'family_name' => 'Smith' }
84
+ # headers:
85
+ # { 'typ' => 'JWT',
86
+ # 'alg' => 'RS256',
87
+ # 'kid' => 'abc123' }
88
+ #
89
+ let(:id_token) { File.read(File.expand_path('../../../fixtures/id_token.txt', __FILE__)) }
90
+
91
+ # If it passes this test, then the id was successfully validated.
92
+ it { is_expected.to_not raise_error }
93
+
94
+ describe 'the auth hash' do
95
+ before(:each) { strategy.callback_phase }
96
+
97
+ subject { env['omniauth.auth'] }
98
+
99
+ it 'should contain the name' do
100
+ expect(subject.info['name']).to eq name
101
+ end
102
+
103
+ it 'should contain the first name' do
104
+ expect(subject.info['first_name']).to eq given_name
105
+ end
106
+
107
+ it 'should contain the last name' do
108
+ expect(subject.info['last_name']).to eq family_name
109
+ end
110
+
111
+ it 'should contain the email' do
112
+ expect(subject.info['email']).to eq email
113
+ end
114
+
115
+ it 'should contain the auth code' do
116
+ expect(subject.credentials['code']).to eq code
117
+ end
118
+
119
+ it 'should contain the session state' do
120
+ expect(subject.extra['session_state']).to eq session_state
121
+ end
122
+ end
123
+ end
124
+
125
+ context 'with an invalid issuer' do
126
+ # payload:
127
+ # { 'iss' => 'https://sts.imposter.net/bunch-of-random-chars', ... }
128
+ #
129
+ let(:id_token) { File.read(File.expand_path('../../../fixtures/id_token_bad_issuer.txt', __FILE__)) }
130
+ it { is_expected.to raise_error JWT::InvalidIssuerError }
131
+ end
132
+
133
+ context 'with an invalid audience' do
134
+ # payload:
135
+ # { 'aud' => 'not the client id', ... }
136
+ #
137
+ let(:id_token) { File.read(File.expand_path('../../../fixtures/id_token_bad_audience.txt', __FILE__)) }
138
+ it { is_expected.to raise_error JWT::InvalidAudError }
139
+ end
140
+
141
+ context 'with a non-matching nonce' do
142
+ # payload:
143
+ # { 'nonce' => 'not my nonce', ... }
144
+ #
145
+ let(:id_token) { File.read(File.expand_path('../../../fixtures/id_token_bad_nonce.txt', __FILE__)) }
146
+ it { is_expected.to raise_error JWT::DecodeError }
147
+ end
148
+
149
+ context 'with the wrong x5c' do
150
+ let(:x5c) { File.read(File.expand_path('../../../fixtures/x5c_different.txt', __FILE__)) }
151
+ let(:id_token) { File.read(File.expand_path('../../../fixtures/id_token.txt', __FILE__)) }
152
+ it { is_expected.to raise_error JWT::VerificationError }
153
+ end
154
+
155
+ context 'with a non-matching c_hash' do
156
+ let(:id_token) { File.read(File.expand_path('../../../fixtures/id_token_bad_chash.txt', __FILE__)) }
157
+ it { is_expected.to raise_error JWT::VerificationError }
158
+ end
159
+
160
+ context 'with a non-matching kid' do
161
+ let(:id_token) { File.read(File.expand_path('../../../fixtures/id_token_bad_kid.txt', __FILE__)) }
162
+ it { is_expected.to raise_error JWT::VerificationError }
163
+ end
164
+
165
+ context 'with no alg header' do
166
+ let(:id_token) { File.read(File.expand_path('../../../fixtures/id_token_no_alg.txt', __FILE__)) }
167
+
168
+ it 'should correctly parse using default RS256' do
169
+ expect(subject).to_not raise_error
170
+ end
171
+
172
+ describe 'the auth hash' do
173
+ subject { env['omniauth.auth'] }
174
+ before(:each) { strategy.callback_phase }
175
+
176
+ it 'should default to RS256' do
177
+ expect(subject.info['name']).to eq name
178
+ end
179
+ end
180
+ end
181
+ end
182
+
183
+ describe '#request_phase' do
184
+ let(:strategy) { described_class.new(app, client_id, tenant) }
185
+ subject { strategy.request_phase }
186
+ before(:each) { strategy.call!(env) }
187
+
188
+ it 'should make a redirect' do
189
+ expect(subject.first).to eq 302
190
+ end
191
+
192
+ it 'should redirect to the correct endpoint' do
193
+ expect(URI(subject[1]['Location']).host).to eq auth_endpoint_host
194
+ end
195
+ end
196
+
197
+ describe '#read_nonce' do
198
+ let(:strategy) { described_class.new(app, client_id, tenant) }
199
+ let(:env) { { 'rack.session' => {} } }
200
+ before(:each) { strategy.call!(env) }
201
+ subject { strategy.send(:read_nonce) }
202
+
203
+ context 'before a nonce is set' do
204
+ it { is_expected.to be nil }
205
+ end
206
+
207
+ context 'after a nonce is set' do
208
+ before(:each) { @nonce = strategy.send(:new_nonce) }
209
+ it 'should match' do
210
+ expect(subject).to eq @nonce
211
+ end
212
+ end
213
+
214
+ context 'twice in a row' do
215
+ before(:each) do
216
+ strategy.send(:new_nonce)
217
+ strategy.send(:read_nonce)
218
+ end
219
+ it { is_expected.to be nil }
220
+ end
221
+ end
222
+ end
@@ -0,0 +1,44 @@
1
+ #-------------------------------------------------------------------------------
2
+ # Copyright (c) 2015 Micorosft Corporation
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #-------------------------------------------------------------------------------
22
+
23
+ require 'webmock/rspec'
24
+ require 'simplecov'
25
+
26
+ SimpleCov.start do
27
+ # Don't measure coverage on test files.
28
+ add_filter 'spec'
29
+ end
30
+
31
+ WebMock.disable_net_connect!(allow_localhost: true)
32
+
33
+ RSpec.configure do |config|
34
+ config.expect_with :rspec do |expectations|
35
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
36
+ end
37
+
38
+ config.mock_with :rspec do |mocks|
39
+ mocks.verify_partial_doubles = true
40
+ end
41
+
42
+ config.warnings = true
43
+ config.order = :random
44
+ end
metadata ADDED
@@ -0,0 +1,245 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: omniauth-azure-activedirectory-davevanfleet
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Microsoft Corporation
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-03-17 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: '2.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: oauth2
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: omniauth
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: omniauth-oauth2
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 1.7.1
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.7.1
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '12.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '12.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.6'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.6'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.49'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.49'
111
+ - !ruby/object:Gem::Dependency
112
+ name: simplecov
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '0.10'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '0.10'
125
+ - !ruby/object:Gem::Dependency
126
+ name: webmock
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '1.21'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '1.21'
139
+ description: Allows developers to authenticate to AAD
140
+ email: nugetaad@microsoft.com
141
+ executables: []
142
+ extensions: []
143
+ extra_rdoc_files: []
144
+ files:
145
+ - ".gitignore"
146
+ - ".rubocop.yml"
147
+ - ".rubocop_todo.yml"
148
+ - ".travis.yml"
149
+ - Gemfile
150
+ - LICENSE.txt
151
+ - README.md
152
+ - RELEASES.md
153
+ - Rakefile
154
+ - examples/rails-todo-list-app/.gitignore
155
+ - examples/rails-todo-list-app/Gemfile
156
+ - examples/rails-todo-list-app/README.md
157
+ - examples/rails-todo-list-app/Rakefile
158
+ - examples/rails-todo-list-app/app/assets/javascripts/application.js
159
+ - examples/rails-todo-list-app/app/assets/stylesheets/application.css
160
+ - examples/rails-todo-list-app/app/controllers/application_controller.rb
161
+ - examples/rails-todo-list-app/app/controllers/home_controller.rb
162
+ - examples/rails-todo-list-app/app/controllers/profile_controller.rb
163
+ - examples/rails-todo-list-app/app/controllers/sessions_controller.rb
164
+ - examples/rails-todo-list-app/app/controllers/signed_in_controller.rb
165
+ - examples/rails-todo-list-app/app/controllers/tasks_controller.rb
166
+ - examples/rails-todo-list-app/app/models/task.rb
167
+ - examples/rails-todo-list-app/app/models/user.rb
168
+ - examples/rails-todo-list-app/app/views/home/index.html.haml
169
+ - examples/rails-todo-list-app/app/views/layouts/application.html.haml
170
+ - examples/rails-todo-list-app/app/views/layouts/signed_in.html.haml
171
+ - examples/rails-todo-list-app/app/views/profile/index.html.haml
172
+ - examples/rails-todo-list-app/app/views/tasks/index.html.haml
173
+ - examples/rails-todo-list-app/bin/bundle
174
+ - examples/rails-todo-list-app/bin/rails
175
+ - examples/rails-todo-list-app/bin/rake
176
+ - examples/rails-todo-list-app/bin/setup
177
+ - examples/rails-todo-list-app/config.ru
178
+ - examples/rails-todo-list-app/config/application.rb
179
+ - examples/rails-todo-list-app/config/boot.rb
180
+ - examples/rails-todo-list-app/config/database.yml
181
+ - examples/rails-todo-list-app/config/environment.rb
182
+ - examples/rails-todo-list-app/config/environments/development.rb
183
+ - examples/rails-todo-list-app/config/environments/production.rb
184
+ - examples/rails-todo-list-app/config/environments/test.rb
185
+ - examples/rails-todo-list-app/config/initializers/assets.rb
186
+ - examples/rails-todo-list-app/config/initializers/backtrace_silencers.rb
187
+ - examples/rails-todo-list-app/config/initializers/cookies_serializer.rb
188
+ - examples/rails-todo-list-app/config/initializers/filter_parameter_logging.rb
189
+ - examples/rails-todo-list-app/config/initializers/inflections.rb
190
+ - examples/rails-todo-list-app/config/initializers/mime_types.rb
191
+ - examples/rails-todo-list-app/config/initializers/omniauth.rb
192
+ - examples/rails-todo-list-app/config/initializers/session_store.rb
193
+ - examples/rails-todo-list-app/config/initializers/wrap_parameters.rb
194
+ - examples/rails-todo-list-app/config/routes.rb
195
+ - examples/rails-todo-list-app/config/secrets.yml
196
+ - examples/rails-todo-list-app/db/schema.rb
197
+ - examples/rails-todo-list-app/public/404.html
198
+ - examples/rails-todo-list-app/public/422.html
199
+ - examples/rails-todo-list-app/public/500.html
200
+ - examples/rails-todo-list-app/public/favicon.ico
201
+ - examples/sinatra-multiple-providers-app/.env
202
+ - examples/sinatra-multiple-providers-app/Gemfile
203
+ - examples/sinatra-multiple-providers-app/README.md
204
+ - examples/sinatra-multiple-providers-app/app.rb
205
+ - examples/sinatra-multiple-providers-app/config.ru
206
+ - lib/omniauth-azure-activedirectory-davevanfleet.rb
207
+ - lib/omniauth/azure_activedirectory_davevanfleet.rb
208
+ - lib/omniauth/azure_activedirectory_davevanfleet/version.rb
209
+ - lib/omniauth/strategies/azure_activedirectory_davevanfleet.rb
210
+ - omniauth-azure-activedirectory-davevanfleet.gemspec
211
+ - spec/fixtures/id_token.txt
212
+ - spec/fixtures/id_token_bad_audience.txt
213
+ - spec/fixtures/id_token_bad_chash.txt
214
+ - spec/fixtures/id_token_bad_issuer.txt
215
+ - spec/fixtures/id_token_bad_kid.txt
216
+ - spec/fixtures/id_token_bad_nonce.txt
217
+ - spec/fixtures/id_token_no_alg.txt
218
+ - spec/fixtures/x5c.txt
219
+ - spec/fixtures/x5c_different.txt
220
+ - spec/omniauth/strategies/azure_activedirectory_davevanfleet_spec.rb
221
+ - spec/spec_helper.rb
222
+ homepage: https://github.com/AzureAD/omniauth-azure-activedirectory
223
+ licenses:
224
+ - MIT
225
+ metadata: {}
226
+ post_install_message:
227
+ rdoc_options: []
228
+ require_paths:
229
+ - lib
230
+ required_ruby_version: !ruby/object:Gem::Requirement
231
+ requirements:
232
+ - - ">="
233
+ - !ruby/object:Gem::Version
234
+ version: '2.2'
235
+ required_rubygems_version: !ruby/object:Gem::Requirement
236
+ requirements:
237
+ - - ">="
238
+ - !ruby/object:Gem::Version
239
+ version: '0'
240
+ requirements: []
241
+ rubygems_version: 3.2.3
242
+ signing_key:
243
+ specification_version: 4
244
+ summary: Azure Active Directory strategy for OmniAuth
245
+ test_files: []