diff --git a/Gemfile b/Gemfile index 75732804e..120a39898 100644 --- a/Gemfile +++ b/Gemfile @@ -13,6 +13,7 @@ gem 'active_hash' gem 'sanitize' gem 'gmaps4rails' gem 'geocoder' +gem 'omniauth-google-oauth2' gem 'omniauth-meetup' gem 'omniauth-facebook' gem 'omniauth-twitter' diff --git a/Gemfile.lock b/Gemfile.lock index ba155adb8..1cd06d3af 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -195,13 +195,19 @@ GEM omniauth-github (1.1.2) omniauth (~> 1.0) omniauth-oauth2 (~> 1.1) + omniauth-google-oauth2 (0.2.10) + addressable (~> 2.3) + jwt (~> 1.0) + multi_json (~> 1.3) + omniauth (>= 1.1.1) + omniauth-oauth2 (~> 1.3.1) omniauth-meetup (0.0.7) omniauth (~> 1.0) omniauth-oauth2 (~> 1.0) omniauth-oauth (1.1.0) oauth omniauth (~> 1.0) - omniauth-oauth2 (1.4.0) + omniauth-oauth2 (1.3.1) oauth2 (~> 1.0) omniauth (~> 1.2) omniauth-twitter (1.2.1) @@ -371,6 +377,7 @@ DEPENDENCIES newrelic_rpm omniauth-facebook omniauth-github + omniauth-google-oauth2 omniauth-meetup omniauth-twitter pg diff --git a/app/controllers/devise_overrides/omniauth_callbacks_controller.rb b/app/controllers/devise_overrides/omniauth_callbacks_controller.rb index 9e4536e7e..d4c1f8750 100644 --- a/app/controllers/devise_overrides/omniauth_callbacks_controller.rb +++ b/app/controllers/devise_overrides/omniauth_callbacks_controller.rb @@ -24,7 +24,7 @@ def all redirect_to new_user_registration_path end end - [:facebook, :twitter, :github, :meetup].each do |provider| + [:facebook, :twitter, :github, :meetup, :google_oauth2].each do |provider| alias_method provider, :all end -end \ No newline at end of file +end diff --git a/app/services/omniauth_providers.rb b/app/services/omniauth_providers.rb index 314da3826..0b0c6715d 100644 --- a/app/services/omniauth_providers.rb +++ b/app/services/omniauth_providers.rb @@ -20,7 +20,12 @@ def self.provider_data key: :meetup, name: 'Meetup', icon: 'fa-calendar' - } + }, + { + key: :google_oauth2, + name: 'Google', + icon: 'fa-google' + }, ] end @@ -48,6 +53,8 @@ def self.user_attributes_from_omniauth(omniauth) self.github_omniauth_attributes(omniauth) when 'meetup' self.meetup_omniauth_attributes(omniauth) + when 'google_oauth2' + self.google_oauth2_omniauth_attributes(omniauth) else raise 'Unknown Provider' end @@ -86,4 +93,12 @@ def self.github_omniauth_attributes(omniauth) def self.meetup_omniauth_attributes(omniauth) self.split_name(omniauth['info']['name']) end + + def self.google_oauth2_omniauth_attributes(omniauth) + { + email: omniauth['info']['email'], + first_name: omniauth['info']['first_name'], + last_name: omniauth['info']['last_name'] + } + end end diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index 55eea13c2..dbd444cca 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -234,6 +234,7 @@ config.omniauth :twitter, ENV['TWITTER_OAUTH_KEY'], ENV['TWITTER_OAUTH_SECRET'] config.omniauth :github, ENV['GITHUB_OAUTH_KEY'], ENV['GITHUB_OAUTH_SECRET'] config.omniauth :meetup, ENV['MEETUP_OAUTH_KEY'], ENV['MEETUP_OAUTH_SECRET'] + config.omniauth :google_oauth2, ENV['GOOGLE_OAUTH_KEY'], ENV['GOOGLE_OAUTH_SECRET'] # ==> Warden configuration # If you want to use other strategies, that are not supported by Devise, or diff --git a/spec/features/omniauth_request_spec.rb b/spec/features/omniauth_request_spec.rb index 69ccb5b60..91b97f5ab 100644 --- a/spec/features/omniauth_request_spec.rb +++ b/spec/features/omniauth_request_spec.rb @@ -43,6 +43,43 @@ end end + context "with a valid google_oauth2 auth" do + let(:google_oauth2_response) { OmniauthResponses.google_oauth2_response } + + before do + OmniAuth.config.mock_auth[:google_oauth2] = OmniAuth::AuthHash.new(google_oauth2_response) + end + + it 'creates a user and authentication if the user does not exist' do + visit user_omniauth_authorize_path(:google_oauth2) + + within '#sign-up' do + click_on 'Sign up' + end + + user = User.last + expect(user).to be_valid + expect(user.first_name).to eq(google_oauth2_response[:info][:first_name]) + expect(user.last_name).to eq(google_oauth2_response[:info][:last_name]) + expect(user.email).to eq(google_oauth2_response[:info][:email]) + + authentication = user.authentications.first + expect(authentication.provider).to eq('google_oauth2') + expect(authentication.uid).to eq(google_oauth2_response[:uid]) + end + + it 'creates a new authentication if the user already exists' do + user = create(:user) + sign_in_as user + + visit user_omniauth_authorize_path(:google_oauth2) + + authentication = user.authentications.first + expect(authentication.provider).to eq('google_oauth2') + expect(authentication.uid).to eq(google_oauth2_response[:uid]) + end + end + context "with a valid twitter auth" do let(:twitter_response) { OmniauthResponses.twitter_response } @@ -193,4 +230,4 @@ expect(page).to have_content('Admin Dashboard') end -end \ No newline at end of file +end diff --git a/spec/services/omniauth_responses.rb b/spec/services/omniauth_responses.rb index 49695d4df..cc917a3cd 100644 --- a/spec/services/omniauth_responses.rb +++ b/spec/services/omniauth_responses.rb @@ -169,4 +169,52 @@ def self.github_response } } end -end \ No newline at end of file + + def self.google_oauth2_response + { + :provider => 'google_oauth2', + :uid => '123456789101112130122', + :info => { + email: 'joe@bloggs.com', + first_name: 'Joe', + image: "https://robohash.org/sitsequiquia.png?size=512x512", + last_name: "Bloggs", + name: "Joe Bloggs", + urls: { Google: "https://plus.google.com/494850544950524948535348525457565050575557" } + }, + :credentials => { + expires: true, + expires_at: 1450062184, + refresh_token: "XYZW...", + token: "ABCDEF..." + }, + :extra => { + id_info: { + at_hash: 'abcdefg', + aud: "50906091245.apps.googleusercontent.com", + azp: "50906091245.apps.googleusercontent.com", + email: "joe@bloggs.com", + email_verified: true, + exp: 1450062184, + iat: 1450058584, + iss: "accounts.google.com", + sub: "102612410550469822979" + }, + id_token: "abcdefghijklmnopqrstuvwxyz", + raw_info: { + email: "joe@bloggs.com", + email_verified: "true", + family_name: "Bloggs", + gender: "male", + given_name: "Joe", + kind: "plus#personOpenIdConnect", + locale: "en", + name: "Joe Bloggs", + picture: "https://robohash.org/sitsequiquia.png?size=512x512", + profile: "https://plus.google.com/494850544950524948535348525457565050575557", + sub: "494850544950524948535348525457565050575557" + }, + } + } + end +end