linkedin_sign_in 0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.travis.yml +18 -0
  4. data/CHANGELOG.md +3 -0
  5. data/Gemfile +6 -0
  6. data/Gemfile.lock +155 -0
  7. data/MIT-LICENSE +20 -0
  8. data/README.md +154 -0
  9. data/Rakefile +40 -0
  10. data/SECURITY.md +3 -0
  11. data/app/controllers/linkedin_sign_in/authorizations_controller.rb +17 -0
  12. data/app/controllers/linkedin_sign_in/base_controller.rb +15 -0
  13. data/app/controllers/linkedin_sign_in/callbacks_controller.rb +27 -0
  14. data/app/helpers/linkedin_sign_in/button_helper.rb +7 -0
  15. data/bin/rails +16 -0
  16. data/config/routes.rb +4 -0
  17. data/lib/linkedin-id-token.rb +190 -0
  18. data/lib/linkedin_sign_in/engine.rb +32 -0
  19. data/lib/linkedin_sign_in/identity.rb +55 -0
  20. data/lib/linkedin_sign_in/redirect_protector.rb +25 -0
  21. data/lib/linkedin_sign_in.rb +10 -0
  22. data/linkedin_sign_in.gemspec +21 -0
  23. data/test/certificate.pem +19 -0
  24. data/test/controllers/authorizations_controller_test.rb +26 -0
  25. data/test/controllers/callbacks_controller_test.rb +36 -0
  26. data/test/dummy/.ruby-version +1 -0
  27. data/test/dummy/Rakefile +6 -0
  28. data/test/dummy/app/assets/config/manifest.js +3 -0
  29. data/test/dummy/app/assets/images/.keep +0 -0
  30. data/test/dummy/app/assets/javascripts/application.js +15 -0
  31. data/test/dummy/app/assets/javascripts/cable.js +13 -0
  32. data/test/dummy/app/assets/javascripts/channels/.keep +0 -0
  33. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  34. data/test/dummy/app/channels/application_cable/channel.rb +4 -0
  35. data/test/dummy/app/channels/application_cable/connection.rb +4 -0
  36. data/test/dummy/app/controllers/application_controller.rb +2 -0
  37. data/test/dummy/app/controllers/concerns/.keep +0 -0
  38. data/test/dummy/app/helpers/application_helper.rb +2 -0
  39. data/test/dummy/app/jobs/application_job.rb +2 -0
  40. data/test/dummy/app/mailers/application_mailer.rb +4 -0
  41. data/test/dummy/app/models/application_record.rb +3 -0
  42. data/test/dummy/app/models/concerns/.keep +0 -0
  43. data/test/dummy/app/views/layouts/application.html.erb +15 -0
  44. data/test/dummy/app/views/layouts/mailer.html.erb +13 -0
  45. data/test/dummy/app/views/layouts/mailer.text.erb +1 -0
  46. data/test/dummy/bin/bundle +3 -0
  47. data/test/dummy/bin/rails +4 -0
  48. data/test/dummy/bin/rake +4 -0
  49. data/test/dummy/bin/setup +36 -0
  50. data/test/dummy/bin/update +31 -0
  51. data/test/dummy/bin/yarn +11 -0
  52. data/test/dummy/config/application.rb +20 -0
  53. data/test/dummy/config/boot.rb +5 -0
  54. data/test/dummy/config/cable.yml +10 -0
  55. data/test/dummy/config/database.yml +25 -0
  56. data/test/dummy/config/environment.rb +5 -0
  57. data/test/dummy/config/environments/development.rb +32 -0
  58. data/test/dummy/config/environments/production.rb +57 -0
  59. data/test/dummy/config/environments/test.rb +33 -0
  60. data/test/dummy/config/initializers/application_controller_renderer.rb +8 -0
  61. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  62. data/test/dummy/config/initializers/content_security_policy.rb +25 -0
  63. data/test/dummy/config/initializers/cookies_serializer.rb +5 -0
  64. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  65. data/test/dummy/config/initializers/inflections.rb +16 -0
  66. data/test/dummy/config/initializers/linkedin_sign_in.rb +4 -0
  67. data/test/dummy/config/initializers/mime_types.rb +4 -0
  68. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  69. data/test/dummy/config/locales/en.yml +33 -0
  70. data/test/dummy/config/puma.rb +34 -0
  71. data/test/dummy/config/routes.rb +2 -0
  72. data/test/dummy/config/spring.rb +6 -0
  73. data/test/dummy/config/storage.yml +34 -0
  74. data/test/dummy/config.ru +5 -0
  75. data/test/dummy/lib/assets/.keep +0 -0
  76. data/test/dummy/log/.keep +0 -0
  77. data/test/dummy/package.json +5 -0
  78. data/test/dummy/public/404.html +67 -0
  79. data/test/dummy/public/422.html +67 -0
  80. data/test/dummy/public/500.html +66 -0
  81. data/test/dummy/public/apple-touch-icon-precomposed.png +0 -0
  82. data/test/dummy/public/apple-touch-icon.png +0 -0
  83. data/test/dummy/public/favicon.ico +0 -0
  84. data/test/helpers/button_helper_test.rb +36 -0
  85. data/test/key.pem +27 -0
  86. data/test/models/identity_test.rb +48 -0
  87. data/test/models/redirect_protector_test.rb +34 -0
  88. data/test/test_helper.rb +28 -0
  89. metadata +267 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ad7912381b74e7f64e9bae51e0a684b300b34e2f4c41c85744cb610ff17607cc
4
+ data.tar.gz: 244c9cff9027b336a4d6bfbdd2028bd5673c1b9f1dc401d7781cdbae5e394a97
5
+ SHA512:
6
+ metadata.gz: 721a1b383a91a13737ed9ab1e01c4b9c655a1482cc61cd740ec6391004ad7021b6787a24b640a19a361cc4e73265af08062e04f60899389dc3e5b01d3cc921b9
7
+ data.tar.gz: 71c4e31c993787c14cd7e8ddcd2f1c27c5118e02226527adb5ef4a6a6355416768fa0ae9dccef47f49e247acd0de56ffbe867082b805b95253ba619c0fdc1b4c
data/.gitignore ADDED
@@ -0,0 +1,13 @@
1
+ .bundle/
2
+ .byebug_history
3
+ log/*.log
4
+ pkg/
5
+ *.gem
6
+
7
+ test/dummy/db/*.sqlite3
8
+ test/dummy/db/*.sqlite3-journal
9
+ test/dummy/log/*.log
10
+ test/dummy/node_modules/
11
+ test/dummy/yarn-error.log
12
+ test/dummy/storage/
13
+ test/dummy/tmp/
data/.travis.yml ADDED
@@ -0,0 +1,18 @@
1
+ language: ruby
2
+ sudo: false
3
+ cache: bundler
4
+
5
+ # Bundler/RubyGems incompat on Ruby 2.5.0
6
+ before_install: gem install bundler
7
+
8
+ rvm:
9
+ - 2.2
10
+ - 2.3
11
+ - 2.4
12
+ - 2.5
13
+ - ruby-head
14
+
15
+ matrix:
16
+ allow_failures:
17
+ - rvm: ruby-head
18
+ fast_finish: true
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ # Changelog
2
+
3
+ Please see [our GitHub "Releases" page](https://github.com/genezys/linkedin_sign_in/releases).
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'rake'
6
+ gem 'byebug'
data/Gemfile.lock ADDED
@@ -0,0 +1,155 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ linkedin_sign_in (0.3)
5
+ oauth2 (>= 1.4.0)
6
+ rails (>= 5.2.0)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ actioncable (5.2.1)
12
+ actionpack (= 5.2.1)
13
+ nio4r (~> 2.0)
14
+ websocket-driver (>= 0.6.1)
15
+ actionmailer (5.2.1)
16
+ actionpack (= 5.2.1)
17
+ actionview (= 5.2.1)
18
+ activejob (= 5.2.1)
19
+ mail (~> 2.5, >= 2.5.4)
20
+ rails-dom-testing (~> 2.0)
21
+ actionpack (5.2.1)
22
+ actionview (= 5.2.1)
23
+ activesupport (= 5.2.1)
24
+ rack (~> 2.0)
25
+ rack-test (>= 0.6.3)
26
+ rails-dom-testing (~> 2.0)
27
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
28
+ actionview (5.2.1)
29
+ activesupport (= 5.2.1)
30
+ builder (~> 3.1)
31
+ erubi (~> 1.4)
32
+ rails-dom-testing (~> 2.0)
33
+ rails-html-sanitizer (~> 1.0, >= 1.0.3)
34
+ activejob (5.2.1)
35
+ activesupport (= 5.2.1)
36
+ globalid (>= 0.3.6)
37
+ activemodel (5.2.1)
38
+ activesupport (= 5.2.1)
39
+ activerecord (5.2.1)
40
+ activemodel (= 5.2.1)
41
+ activesupport (= 5.2.1)
42
+ arel (>= 9.0)
43
+ activestorage (5.2.1)
44
+ actionpack (= 5.2.1)
45
+ activerecord (= 5.2.1)
46
+ marcel (~> 0.3.1)
47
+ activesupport (5.2.1)
48
+ concurrent-ruby (~> 1.0, >= 1.0.2)
49
+ i18n (>= 0.7, < 2)
50
+ minitest (~> 5.1)
51
+ tzinfo (~> 1.1)
52
+ addressable (2.5.2)
53
+ public_suffix (>= 2.0.2, < 4.0)
54
+ arel (9.0.0)
55
+ builder (3.2.3)
56
+ byebug (10.0.2)
57
+ concurrent-ruby (1.0.5)
58
+ crack (0.4.3)
59
+ safe_yaml (~> 1.0.0)
60
+ crass (1.0.4)
61
+ erubi (1.7.1)
62
+ faraday (0.15.3)
63
+ multipart-post (>= 1.2, < 3)
64
+ globalid (0.4.1)
65
+ activesupport (>= 4.2.0)
66
+ hashdiff (0.3.7)
67
+ i18n (1.1.1)
68
+ concurrent-ruby (~> 1.0)
69
+ jwt (2.1.0)
70
+ loofah (2.2.3)
71
+ crass (~> 1.0.2)
72
+ nokogiri (>= 1.5.9)
73
+ mail (2.7.1)
74
+ mini_mime (>= 0.1.1)
75
+ marcel (0.3.3)
76
+ mimemagic (~> 0.3.2)
77
+ method_source (0.9.1)
78
+ mimemagic (0.3.2)
79
+ mini_mime (1.0.1)
80
+ mini_portile2 (2.3.0)
81
+ minitest (5.11.3)
82
+ multi_json (1.13.1)
83
+ multi_xml (0.6.0)
84
+ multipart-post (2.0.0)
85
+ nio4r (2.3.1)
86
+ nokogiri (1.8.5)
87
+ mini_portile2 (~> 2.3.0)
88
+ oauth2 (1.4.1)
89
+ faraday (>= 0.8, < 0.16.0)
90
+ jwt (>= 1.0, < 3.0)
91
+ multi_json (~> 1.3)
92
+ multi_xml (~> 0.5)
93
+ rack (>= 1.2, < 3)
94
+ public_suffix (3.0.3)
95
+ rack (2.0.5)
96
+ rack-test (1.1.0)
97
+ rack (>= 1.0, < 3)
98
+ rails (5.2.1)
99
+ actioncable (= 5.2.1)
100
+ actionmailer (= 5.2.1)
101
+ actionpack (= 5.2.1)
102
+ actionview (= 5.2.1)
103
+ activejob (= 5.2.1)
104
+ activemodel (= 5.2.1)
105
+ activerecord (= 5.2.1)
106
+ activestorage (= 5.2.1)
107
+ activesupport (= 5.2.1)
108
+ bundler (>= 1.3.0)
109
+ railties (= 5.2.1)
110
+ sprockets-rails (>= 2.0.0)
111
+ rails-dom-testing (2.0.3)
112
+ activesupport (>= 4.2.0)
113
+ nokogiri (>= 1.6)
114
+ rails-html-sanitizer (1.0.4)
115
+ loofah (~> 2.2, >= 2.2.2)
116
+ railties (5.2.1)
117
+ actionpack (= 5.2.1)
118
+ activesupport (= 5.2.1)
119
+ method_source
120
+ rake (>= 0.8.7)
121
+ thor (>= 0.19.0, < 2.0)
122
+ rake (12.3.1)
123
+ safe_yaml (1.0.4)
124
+ sprockets (3.7.2)
125
+ concurrent-ruby (~> 1.0)
126
+ rack (> 1, < 3)
127
+ sprockets-rails (3.2.1)
128
+ actionpack (>= 4.0)
129
+ activesupport (>= 4.0)
130
+ sprockets (>= 3.0.0)
131
+ thor (0.20.0)
132
+ thread_safe (0.3.6)
133
+ tzinfo (1.2.5)
134
+ thread_safe (~> 0.1)
135
+ webmock (3.4.2)
136
+ addressable (>= 2.3.6)
137
+ crack (>= 0.3.2)
138
+ hashdiff
139
+ websocket-driver (0.7.0)
140
+ websocket-extensions (>= 0.1.0)
141
+ websocket-extensions (0.1.3)
142
+
143
+ PLATFORMS
144
+ ruby
145
+
146
+ DEPENDENCIES
147
+ bundler (~> 1.15)
148
+ byebug
149
+ jwt (>= 1.5.6)
150
+ linkedin_sign_in!
151
+ rake
152
+ webmock (>= 3.4.2)
153
+
154
+ BUNDLED WITH
155
+ 1.16.4
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2018 Vincent Robert
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,154 @@
1
+ This gem is shamlessly based on [Google SignIn by Basecamp](https://github.com/basecamp/google_sign_in).
2
+
3
+ # Linkedin Sign-In for Rails
4
+
5
+ This gem allows you to add Linkedin sign-in to your Rails app. You can let users sign up for and sign in to your service
6
+ with their Linkedin accounts.
7
+
8
+
9
+ ## Installation
10
+
11
+ Add `linkedin_sign_in` to your Rails app’s Gemfile and run `bundle install`:
12
+
13
+ ```ruby
14
+ gem 'linkedin_sign_in'
15
+ ```
16
+
17
+ Linkedin Sign-In for Rails requires Rails 5.2 or newer.
18
+
19
+
20
+ ## Configuration
21
+
22
+ First, set up an OAuth 2.0 Client ID in the Linkedin API Console:
23
+
24
+ 1. Go to the [Developer Portal](https://www.linkedin.com/developer/apps).
25
+
26
+ 2. Create an application.
27
+
28
+ 3. Submit your application information.
29
+
30
+ 4. You are presented with a client ID and client secret. Save these.
31
+
32
+ 5. This gem adds a single OAuth callback to your app at `/linkedin_sign_in/callback`. Under **Authorized Redirect URLs**,
33
+ add that callback for your application’s domain: for example, `https://example.com/linkedin_sign_in/callback`.
34
+
35
+ To use Linkedin sign-in in development, you’ll need to add another redirect URI for your local environment, like
36
+ `http://localhost:3000/linkedin_sign_in/callback`. For security reasons, we recommend using a separate
37
+ client ID for local development. Repeat these instructions to set up a new client ID for development.
38
+
39
+ 6. Click the button labeled Update.
40
+
41
+ With your client ID set up, configure your Rails application to use it. Run `bin/rails credentials:edit` to edit your
42
+ app’s [encrypted credentials](https://guides.rubyonrails.org/security.html#custom-credentials) and add the following:
43
+
44
+ ```yaml
45
+ linkedin_sign_in:
46
+ client_id: [Your client ID here]
47
+ client_secret: [Your client secret here]
48
+ ```
49
+
50
+ You’re all set to use Linkedin sign-in now. The gem automatically uses the client ID and client secret in your credentials.
51
+
52
+ Alternatively, you can provide the client ID and client secret using ENV variables. Add a new initializer that sets
53
+ `config.linkedin_sign_in.client_id` and `config.linkedin_sign_in.client_secret`:
54
+
55
+ ```ruby
56
+ # config/initializers/linkedin_sign_in.rb
57
+ Rails.application.configure do
58
+ config.linkedin_sign_in.client_id = ENV['linkedin_sign_in_client_id']
59
+ config.linkedin_sign_in.client_secret = ENV['linkedin_sign_in_client_secret']
60
+ end
61
+ ```
62
+
63
+ **⚠️ Important:** Take care to protect your client secret from disclosure to third parties.
64
+
65
+
66
+ ## Usage
67
+
68
+ This gem provides a `linkedin_sign_in_button` helper. It generates a button which initiates Linkedin sign-in:
69
+
70
+ ```erb
71
+ <%= linkedin_sign_in_button 'Sign in with my Linkedin account', proceed_to: create_login_url %>
72
+
73
+ <%= linkedin_sign_in_button image_tag('linkedin_logo.png', alt: 'Linkedin'), proceed_to: create_login_url %>
74
+
75
+ <%= linkedin_sign_in_button proceed_to: create_login_url do %>
76
+ Sign in with my <%= image_tag('linkedin_logo.png', alt: 'Linkedin') %> account
77
+ <% end %>
78
+ ```
79
+
80
+ The `proceed_to` argument is required. After authenticating with Linkedin, the gem redirects to `proceed_to`, providing
81
+ a Linkedin ID token in `flash[:linkedin_sign_in_token]`. Your application decides what to do with it:
82
+
83
+ ```ruby
84
+ # config/routes.rb
85
+ Rails.application.routes.draw do
86
+ # ...
87
+ get 'login', to: 'logins#new'
88
+ get 'login/create', to: 'logins#create', as: :create_login
89
+ end
90
+ ```
91
+
92
+ ```ruby
93
+ # app/controllers/logins_controller.rb
94
+ class LoginsController < ApplicationController
95
+ def new
96
+ end
97
+
98
+ def create
99
+ if user = authenticate_with_linkedin
100
+ cookies.signed[:user_id] = user.id
101
+ redirect_to user
102
+ else
103
+ redirect_to new_session_url, alert: 'authentication_failed'
104
+ end
105
+ end
106
+
107
+ private
108
+ def authenticate_with_linkedin
109
+ if flash[:linkedin_sign_in_token].present?
110
+ User.find_by linkedin_id: LinkedinSignIn::Identity.new(flash[:linkedin_sign_in_token]).user_id
111
+ end
112
+ end
113
+ end
114
+ ```
115
+
116
+ (The above example assumes the user has already signed up for your service and that you’re storing their Linkedin user ID
117
+ in the `User#linkedin_id` attribute.)
118
+
119
+ For security reasons, the `proceed_to` URL you provide to `linkedin_sign_in_button` is required to reside on the same
120
+ origin as your application. This means it must have the same protocol, host, and port as the page where
121
+ `linkedin_sign_in_button` is used. We enforce this before redirecting to the `proceed_to` URL to guard against
122
+ [open redirects](https://www.owasp.org/index.php/Unvalidated_Redirects_and_Forwards_Cheat_Sheet).
123
+
124
+ ### `LinkedinSignIn::Identity`
125
+
126
+ The `LinkedinSignIn::Identity` class decodes and verifies the integrity of a Linkedin ID token. It exposes the profile
127
+ information contained in the token via the following instance methods:
128
+
129
+ * `name`
130
+
131
+ * `email_address`
132
+
133
+ * `user_id`: A string that uniquely identifies a single Linkedin user. Use this, not `email_address`, to associate a
134
+ Linkedin user with an application user. A Linkedin user’s email address may change, but their `user_id` will remain constant.
135
+
136
+ * `email_verified?`
137
+
138
+ * `avatar_url`
139
+
140
+ * `locale`
141
+
142
+ * `hosted_domain`: The user’s hosted G Suite domain, provided only if they belong to a G Suite.
143
+
144
+
145
+ ## Security
146
+
147
+ For information on our security response procedure, see [SECURITY.md](SECURITY.md).
148
+
149
+
150
+ ## License
151
+
152
+ Linkedin Sign-In for Rails is released under the [MIT License](https://opensource.org/licenses/MIT).
153
+
154
+ Linkedin is a registered trademark of Linkedin LLC. This project is not operated by or in any way affiliated with Linkedin LLC.
data/Rakefile ADDED
@@ -0,0 +1,40 @@
1
+ require "bundler/setup"
2
+ require "bundler/gem_tasks"
3
+ require "rake/testtask"
4
+
5
+ Rake::TestTask.new do |test|
6
+ test.libs << "test"
7
+ test.test_files = FileList["test/**/*_test.rb"]
8
+ test.warning = false
9
+ end
10
+
11
+ task default: :test
12
+
13
+ desc "Generates an X509 certificate for decoding test ID tokens"
14
+ task "test:certificate:generate" do
15
+ require "openssl"
16
+ require "active_support"
17
+ require "active_support/core_ext/integer/time"
18
+
19
+ key = OpenSSL::PKey::RSA.new(File.read(File.expand_path("test/key.pem", __dir__)))
20
+
21
+ certificate = OpenSSL::X509::Certificate.new
22
+ certificate.subject = certificate.issuer = OpenSSL::X509::Name.parse("/CN=linkedin-sign-in-for-rails.example.com")
23
+ certificate.not_before = Time.now
24
+ certificate.not_after = 5.years.from_now
25
+ certificate.public_key = key.public_key
26
+ certificate.serial = 0
27
+ certificate.version = 1
28
+
29
+ extension_factory = OpenSSL::X509::ExtensionFactory.new
30
+ extension_factory.subject_certificate = certificate
31
+ extension_factory.issuer_certificate = certificate
32
+ certificate.extensions = [
33
+ extension_factory.create_extension("basicConstraints", "CA:FALSE", true),
34
+ extension_factory.create_extension("keyUsage", "digitalSignature", true),
35
+ extension_factory.create_extension("extendedKeyUsage", "clientAuth", true)
36
+ ]
37
+
38
+ certificate.sign(key, OpenSSL::Digest::SHA1.new)
39
+ File.write(File.expand_path("test/certificate.pem", __dir__), certificate.to_pem)
40
+ end
data/SECURITY.md ADDED
@@ -0,0 +1,3 @@
1
+ Contrary to Basecamp with the Google SignIn gem, I cannot afford the time to maintain the security of this gem.
2
+
3
+ Use at your own risk!
@@ -0,0 +1,17 @@
1
+ require 'securerandom'
2
+
3
+ class LinkedinSignIn::AuthorizationsController < LinkedinSignIn::BaseController
4
+ def create
5
+ redirect_to login_url(scope: 'r_basicprofile r_emailaddress', state: state),
6
+ flash: { proceed_to: params.require(:proceed_to), state: state }
7
+ end
8
+
9
+ private
10
+ def login_url(**params)
11
+ client.auth_code.authorize_url(prompt: 'login', **params)
12
+ end
13
+
14
+ def state
15
+ @state ||= SecureRandom.base64(24)
16
+ end
17
+ end
@@ -0,0 +1,15 @@
1
+ require 'oauth2'
2
+
3
+ class LinkedinSignIn::BaseController < ActionController::Base
4
+ protect_from_forgery with: :exception
5
+
6
+ private
7
+ def client
8
+ @client ||= OAuth2::Client.new \
9
+ LinkedinSignIn.client_id,
10
+ LinkedinSignIn.client_secret,
11
+ authorize_url: 'https://www.linkedin.com/oauth/v2/authorization',
12
+ token_url: 'https://www.linkedin.com/oauth/v2/accessToken',
13
+ redirect_uri: callback_url
14
+ end
15
+ end
@@ -0,0 +1,27 @@
1
+ require_dependency 'linkedin_sign_in/redirect_protector'
2
+
3
+ class LinkedinSignIn::CallbacksController < LinkedinSignIn::BaseController
4
+ def show
5
+ if valid_request?
6
+ redirect_to proceed_to_url, flash: { linkedin_sign_in_token: token }
7
+ else
8
+ head :unprocessable_entity
9
+ end
10
+ rescue LinkedinSignIn::RedirectProtector::Violation => error
11
+ logger.error error.message
12
+ head :bad_request
13
+ end
14
+
15
+ private
16
+ def valid_request?
17
+ flash[:state].present? && params.require(:state) == flash[:state] && params[:error].blank?
18
+ end
19
+
20
+ def proceed_to_url
21
+ flash[:proceed_to].tap { |url| LinkedinSignIn::RedirectProtector.ensure_same_origin(url, request.url) }
22
+ end
23
+
24
+ def token
25
+ client.auth_code.get_token(params.require(:code)).token
26
+ end
27
+ end
@@ -0,0 +1,7 @@
1
+ module LinkedinSignIn::ButtonHelper
2
+ def linkedin_sign_in_button(text = nil, proceed_to:, **options, &block)
3
+ form_with url: linkedin_sign_in.authorization_path, local: true do
4
+ hidden_field_tag(:proceed_to, proceed_to, id: nil) + button_tag(text, name: nil, **options, &block)
5
+ end
6
+ end
7
+ end
data/bin/rails ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails gems
3
+ # installed from the root of your application.
4
+
5
+ ENGINE_ROOT = File.expand_path('..', __dir__)
6
+ ENGINE_PATH = File.expand_path('../lib/blorgh/engine', __dir__)
7
+ APP_PATH = File.expand_path('../test/dummy/config/application', __dir__)
8
+
9
+ # Set up gems listed in the Gemfile.
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
11
+ require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
12
+
13
+ require 'rails'
14
+ require 'action_controller/railtie'
15
+ require 'rails/test_unit/railtie'
16
+ require 'rails/engine/commands'
data/config/routes.rb ADDED
@@ -0,0 +1,4 @@
1
+ LinkedinSignIn::Engine.routes.draw do
2
+ resource :authorization, only: :create
3
+ resource :callback, only: :show
4
+ end