linkedin_sign_in 0.3

Sign up to get free protection for your applications and to get access to all the features.
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