google_sign_in 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ce2cbe6f38376f6f4ec06a59c7b0fcb916ed1611
4
+ data.tar.gz: 4acaea345f5840be79e9a2d77b301e96e2eaaf90
5
+ SHA512:
6
+ metadata.gz: db6f84a43691f47461ad4d7572d165fd23b2010fbc1f28b96dd81c624eef1e1af3b5070b56d1dce1fcb8293ce85d8dd74e3b134ca75aa14d24b6be94216d633d
7
+ data.tar.gz: 7c3a4756ceaf4e6a7a96fee9ddf361843b6c46f61c825023ab2319290d46f0cdcb799fa24eea4d88f0e7bc34eaa62a3074badd56b51035a13f311a59a319b514
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'rake'
6
+ gem 'byebug'
@@ -0,0 +1,40 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ google_sign_in (0.1)
5
+ activesupport (>= 5.1)
6
+ google-id-token (>= 1.3.1)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ activesupport (5.1.1)
12
+ concurrent-ruby (~> 1.0, >= 1.0.2)
13
+ i18n (~> 0.7)
14
+ minitest (~> 5.1)
15
+ tzinfo (~> 1.1)
16
+ byebug (9.0.6)
17
+ concurrent-ruby (1.0.5)
18
+ google-id-token (1.3.1)
19
+ jwt
20
+ multi_json
21
+ i18n (0.8.1)
22
+ jwt (1.5.6)
23
+ minitest (5.10.2)
24
+ multi_json (1.12.1)
25
+ rake (12.0.0)
26
+ thread_safe (0.3.6)
27
+ tzinfo (1.2.3)
28
+ thread_safe (~> 0.1)
29
+
30
+ PLATFORMS
31
+ ruby
32
+
33
+ DEPENDENCIES
34
+ bundler (~> 1.15)
35
+ byebug
36
+ google_sign_in!
37
+ rake
38
+
39
+ BUNDLED WITH
40
+ 1.15.0
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2017 David Heinemeier Hansson, Basecamp
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.
@@ -0,0 +1,73 @@
1
+ # Google Sign-In for Rails
2
+
3
+ Google Sign-In provides an easy and secure way to let users signin into and up for your service,
4
+ without adding yet-another per-app email/password combination. Integrating it into your Rails app
5
+ should be drop-in easy. This gem makes it so.
6
+
7
+ The only configuration needed is setting the Google client id for your application. [Google has a
8
+ tutorial on how to setup a client id](https://developers.google.com/identity/sign-in/web/server-side-flow#step_1_create_a_client_id_and_client_secret).
9
+
10
+ Once you have your client id, create a `config/initializers/google_sign_in_client_id.rb` file with this:
11
+ `GoogleSignIn::Identity.client_id = <THAT CLIENT ID YOU GOT FROM GOOGLE>`
12
+
13
+ Now you can use the sign-in integration on your signup or sigin screen.
14
+
15
+ ## Example
16
+
17
+ Here's the most basic example:
18
+
19
+ ```ruby
20
+ # app/views/sessions/new.html.erb
21
+ <%= google_sign_in(url: session_path) do %>
22
+ <%= button_tag("Signin with Google") %>
23
+ <% end %>
24
+ ```
25
+
26
+ The `url` option is the URL that the hidden form will be submitted against along with the Google ID Token
27
+ that's set after the user has picked the account and authenticated in the pop-up window Google provides.
28
+
29
+ You can then use that in a sessions controller like so:
30
+
31
+ ```ruby
32
+ class SessionsController < ApplicationController
33
+ def new
34
+ end
35
+
36
+ def create
37
+ if user = authenticate_via_google
38
+ cookies.signed[:user_id] = user.id
39
+ redirect_to user
40
+ else
41
+ redirect_to new_session_url, alert: "authentication_failed"
42
+ end
43
+ end
44
+
45
+ private
46
+ def authenticate_via_google
47
+ if params[:google_id_token].present?
48
+ User.find_by google_id: GoogleSignIn::Identity.new(params[:google_id_token]).user_id
49
+ end
50
+ end
51
+ end
52
+ ```
53
+
54
+ (This example assumes that a user has already signed up for your service using Google Sign-In and that
55
+ you're storing the Google user id in the `User#google_id` attribute).
56
+
57
+ That's it! You can checkout the `GoogleSignIn::Identity` class for the thin wrapping it provides around
58
+ the decoding of the Google ID Token using the google-id-token library. Interrogating this identity object
59
+ for profile details is particularly helpful when you use Google for signup, as you can get the name, email
60
+ address, avatar url, and locale through it.
61
+
62
+ ## Unreleased gem caveat
63
+
64
+ The gem google-id-token is currently behind its GitHub repository on the release schedule. The latest release
65
+ is version 1.3.1 from 2015. So for now, you should depend on the github version in your app's Gemfile:
66
+
67
+ ```ruby
68
+ gem 'google-id-token', github: 'google/google-id-token'
69
+ ```
70
+
71
+ ## License
72
+
73
+ Google Sign-In for Rails is released under the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,10 @@
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
+ end
9
+
10
+ task default: :test
@@ -0,0 +1,19 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'google_sign_in'
3
+ s.version = '0.1'
4
+ s.authors = 'David Heinemeier Hansson'
5
+ s.email = 'david@basecamp.com'
6
+ s.summary = 'Sign in (or up) with Google for Rails applications'
7
+ s.homepage = 'https://github.com/basecamp/google_sign_in'
8
+ s.license = 'MIT'
9
+
10
+ s.required_ruby_version = '>= 1.9.3'
11
+
12
+ s.add_dependency 'activesupport', '>= 5.1'
13
+ s.add_dependency 'google-id-token', '>= 1.3.1'
14
+
15
+ s.add_development_dependency 'bundler', '~> 1.15'
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- test/*`.split("\n")
19
+ end
@@ -0,0 +1,2 @@
1
+ require 'google_sign_in/identity'
2
+ require 'google_sign_in/railtie' if defined?(Rails)
@@ -0,0 +1,60 @@
1
+ require 'google_sign_in/identity'
2
+
3
+ module GoogleSignIn
4
+ module Helper
5
+ def google_sign_in(url:, &block)
6
+ content_for :head,
7
+ google_sign_in_javacript_include_tag +
8
+ google_sign_in_client_id_meta_tag
9
+
10
+ google_sign_in_javascript_tag +
11
+ google_sign_in_hidden_form_tag(url: url) +
12
+ google_sign_in_click_handler(&block)
13
+ end
14
+
15
+ private
16
+ def google_sign_in_javacript_include_tag
17
+ javascript_include_tag "https://apis.google.com/js/platform.js?onload=setupGoogleSignIn", async: true, defer: true
18
+ end
19
+
20
+ def google_sign_in_client_id_meta_tag
21
+ tag.meta name: "google-signin-client_id", content: GoogleSignIn::Identity.client_id
22
+ end
23
+
24
+ def google_sign_in_hidden_form_tag(url:)
25
+ form_with url: url, id: "google_signin", html: { style: "display: none" } do |form|
26
+ form.hidden_field :google_id_token, id: "google_id_token"
27
+ end
28
+ end
29
+
30
+ def google_sign_in_click_handler(&block)
31
+ tag.div(onclick: 'selectGoogleSignInAccount(event)') { capture(&block) }
32
+ end
33
+
34
+ def google_sign_in_javascript_tag
35
+ javascript_tag(<<-EOS
36
+ function setupGoogleSignIn() {
37
+ gapi.load("auth2", function () { gapi.auth2.init() })
38
+ }
39
+
40
+ function selectGoogleSignInAccount(event) {
41
+ event.preventDefault()
42
+
43
+ options = new gapi.auth2.SigninOptionsBuilder
44
+ options.setPrompt("select_account")
45
+
46
+ gapi.auth2.getAuthInstance().signIn(options).then(function (googleUser) {
47
+ var token = googleUser.getAuthResponse().id_token
48
+
49
+ if (token !== null) {
50
+ document.getElementById('google_id_token').value = token
51
+ document.getElementById('google_signin').submit()
52
+ gapi.auth2.getAuthInstance().signOut()
53
+ }
54
+ })
55
+ }
56
+ EOS
57
+ )
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,63 @@
1
+ require 'google-id-token'
2
+ require 'active_support/core_ext/class/attribute'
3
+ require 'active_support/core_ext/numeric/time'
4
+
5
+ module GoogleSignIn
6
+ class Identity
7
+ class_attribute :client_id
8
+
9
+ class_attribute :token_expiry
10
+ self.token_expiry = 5.minutes
11
+
12
+ class_attribute :logger
13
+ self.logger = defined?(Rails) ? Rails.logger : Logger.new(STDOUT)
14
+
15
+ def initialize(token)
16
+ ensure_client_id_present
17
+ set_extracted_payload(token)
18
+ ensure_proper_audience
19
+ end
20
+
21
+ def user_id
22
+ @payload["sub"]
23
+ end
24
+
25
+ def name
26
+ @payload["name"]
27
+ end
28
+
29
+ def email_address
30
+ @payload["email"]
31
+ end
32
+
33
+ def email_verified?
34
+ @payload["email_verified"] == "true"
35
+ end
36
+
37
+ def avatar_url
38
+ @payload["picture"]
39
+ end
40
+
41
+ def locale
42
+ @payload["locale"]
43
+ end
44
+
45
+ private
46
+ def ensure_client_id_present
47
+ if client_id.blank?
48
+ raise ArgumentError, "GoogleSignIn.client_id must be set to validate identity"
49
+ end
50
+ end
51
+
52
+ def set_extracted_payload(token)
53
+ @payload = GoogleIDToken::Validator.new(expiry: token_expiry).check(token, client_id)
54
+ rescue GoogleIDToken::ValidationError => e
55
+ logger.error "Google token failed to validate (#{e.message})"
56
+ @payload = {}
57
+ end
58
+
59
+ def ensure_proper_audience
60
+ @payload["aud"].include?(client_id)
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,12 @@
1
+ require 'rails/railtie'
2
+ require 'google_sign_in/helper'
3
+
4
+ module GoogleSignIn
5
+ class Engine < ::Rails::Engine
6
+ initializer :google_sign_in do |app|
7
+ ActiveSupport.on_load :action_controller do
8
+ ActionController::Base.send :helper, GoogleSignIn::Helper
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,9 @@
1
+ require 'test_helper'
2
+ require 'google_sign_in/identity'
3
+
4
+ class GoogleSignIn::IdentityTest < ActiveSupport::TestCase
5
+ test "client_id must be set" do
6
+ GoogleSignIn::Identity.client_id = nil
7
+ assert_raises(ArgumentError) { GoogleSignIn::Identity.new("some_fake_token") }
8
+ end
9
+ end
@@ -0,0 +1,4 @@
1
+ require 'bundler/setup'
2
+ require 'active_support'
3
+ require 'active_support/testing/autorun'
4
+ require 'byebug'
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: google_sign_in
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - David Heinemeier Hansson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-05-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '5.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '5.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: google-id-token
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.3.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.3.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.15'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.15'
55
+ description:
56
+ email: david@basecamp.com
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files: []
60
+ files:
61
+ - Gemfile
62
+ - Gemfile.lock
63
+ - MIT-LICENSE
64
+ - README.md
65
+ - Rakefile
66
+ - google_sign_in.gemspec
67
+ - lib/google_sign_in.rb
68
+ - lib/google_sign_in/helper.rb
69
+ - lib/google_sign_in/identity.rb
70
+ - lib/google_sign_in/railtie.rb
71
+ - test/identity_test.rb
72
+ - test/test_helper.rb
73
+ homepage: https://github.com/basecamp/google_sign_in
74
+ licenses:
75
+ - MIT
76
+ metadata: {}
77
+ post_install_message:
78
+ rdoc_options: []
79
+ require_paths:
80
+ - lib
81
+ required_ruby_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: 1.9.3
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ requirements: []
92
+ rubyforge_project:
93
+ rubygems_version: 2.6.11
94
+ signing_key:
95
+ specification_version: 4
96
+ summary: Sign in (or up) with Google for Rails applications
97
+ test_files:
98
+ - test/identity_test.rb
99
+ - test/test_helper.rb