Skip to content

Commit

Permalink
Otp google (#5)
Browse files Browse the repository at this point in the history
* Forcing SSL in production

* upgrading JWT to version 2.4.1

* Adding development credentials and updating .gitignore

* Adding omniauth initializer

* Google OAuth code set up

* First iteration: works

* Adding Down gem to manage downloads

* User's avatar is now downloaded from Google if any

Co-authored-by: Stephane Paquet <spaquet@up4b.com>
  • Loading branch information
spaquet and Stephane Paquet authored Jun 8, 2022
1 parent 3ab4e1b commit 5682fc7
Show file tree
Hide file tree
Showing 14 changed files with 110 additions and 8 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,5 @@
!/app/assets/builds/.keep

/node_modules

/config/credentials/development.key
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ gem "bootsnap", require: false
# Use Sass to process CSS
# gem "sassc-rails"

# Download
gem "down", "~> 5.0"

# Active storage validations [https://github.com/igorkasyanchuk/active_storage_validations]
gem "active_storage_validations", "~> 0.9.8"

Expand Down
5 changes: 4 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ GEM
irb (>= 1.3.6)
reline (>= 0.2.7)
digest (3.1.0)
down (5.3.1)
addressable (~> 2.8)
erubi (1.10.0)
faraday (2.3.0)
faraday-net_http (~> 2.0)
Expand All @@ -124,7 +126,7 @@ GEM
activesupport (>= 5.0.0)
jsbundling-rails (1.0.2)
railties (>= 6.0.0)
jwt (2.4.0)
jwt (2.4.1)
kredis (1.2.0)
activesupport (>= 6.0.0)
redis (~> 4.2)
Expand Down Expand Up @@ -280,6 +282,7 @@ DEPENDENCIES
capybara
cssbundling-rails
debug
down (~> 5.0)
image_processing (~> 1.2)
jbuilder
jsbundling-rails
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ Logos [https://www.svgrepo.com/vectors/google/]
Icons [https://heroicons.com/]

## LICENSE
To Read: [https://www.linkedin.com/pulse/how-we-picked-our-open-source-license-cloudkeeper-framework-kamp/]
To Read: [https://www.linkedin.com/pulse/how-we-picked-our-open-source-license-cloudkeeper-framework-kamp/]

TMP: [https://blog.saeloun.com/2019/10/10/rails-6-adds-support-for-multi-environment-credentials.html]
68 changes: 68 additions & 0 deletions app/controllers/sessions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,72 @@ def destroy

def new
end

def omniauth
user = from_omniauth(request.env["omniauth.auth"])
if user.valid?
session[:user_id] = user.id
after_login_path = session[:user_return_to] || root_path
login user
redirect_to after_login_path, notice: "Signed in."
else
redirect_to login_path, alert: "There was an error while trying to authenticate you using Google."
end
end

private

def from_omniauth(response)
require "down"

email = response[:info][:email]
# Check if user exists with this email
u = User.find_by(email: email)
if u && u.provider == nil
# Return to the login page with an error
redirect_to login_path, alert: "This email is already registered with an account."
return
end

# If the user does not exist with this email, then process
user = User.find_by(uid: response[:uid], provider: response[:provider])
if user
# The user exists, so update the user's info
user.profile.nickname = response[:info][:name]
else
# The user does not exist, so create a new user
user = User.new(email: email, uid: response[:uid], provider: response[:provider])
user.build_profile
user.profile.nickname = response[:info][:name]
user.password = SecureRandom.hex(16)
if response[:info][:email_verified]
user.confirmed = true
user.confirmed_at = Time.current
else
user.send_confirmation_email!
end
end

image_url = response[:info][:image]
# remove the size parameter at the end of the image url
pattern = /=s\d+/

last = image_url.rindex(pattern)
if last
image_url = image_url[0..last-1]
end

tempavatar = Down.download(image_url)
filename = SecureRandom.hex(16)
user.profile.avatar.attach(io: tempavatar, filename: filename, content_type: tempavatar.content_type)

# user.oauth_token = response["credentials"]["token"]
# user.oauth_expires_at = response["credentials"]["expires_at"]

# Save the user
user.save!

# Return the user
user
end
end
2 changes: 1 addition & 1 deletion app/views/sessions/new.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<% end %>
<h4 class="text-center text-sm font-light text-slate-500 py-3">-- Or --</h4>
<div class="mb-4">
<%= link_to new_password_path, class: "w-full block py-3 font-medium text-white bg-green-400 rounded-xl" do %>
<%= button_to "/auth/google_oauth2", class: "w-full block py-3 font-medium text-white bg-green-400 rounded-xl", data: { turbo: false } do %>
<div class="flex flex-1 justify-center items-center">
<svg class="h-7 w-7 pr-2" fill="currentColor" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<path d="M11.99,13.9 L11.99,10.18 L21.35,10.18 C21.49,10.81 21.6,11.4 21.6,12.23 C21.6,17.94 17.77,22 12,22 C6.48,22 2,17.52 2,12 C2,6.48 6.48,2 12,2 C14.7,2 16.96,2.99 18.69,4.61 L15.85,7.37 C15.13,6.69 13.87,5.89 12,5.89 C8.69,5.89 5.99,8.64 5.99,12.01 C5.99,15.38 8.69,18.13 12,18.13 C15.83,18.13 17.24,15.48 17.5,13.91 L11.99,13.91 L11.99,13.9 Z" id="Shape"></path>
Expand Down
4 changes: 2 additions & 2 deletions app/views/shared/_top_navigation.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@
<% if user_signed_in? %>
<div data-controller="toggle" class="relative inline-block">
<button type="button" data-action="click->toggle#toggle">
<div class="w-10 rounded-full">
<div class="w-10">
<%= image_tag current_user.profile.avatar.variant(resize_to_limit: [100, 100]),
width: 100, height: 100 if current_user.profile.avatar.attached? %>
width: 100, height: 100, class: "rounded-full" if current_user.profile.avatar.attached? %>
<%= content_tag :img, nil, src: "http://tinygraphs.com/spaceinvaders/#{current_user.profile.nickname.strip}?theme=frogideas&numcolors=4&size=100&fmt=svg", width: 100, height: 100,
class: "rounded-full",
'data-image-uploader-target': 'preview' unless current_user.profile.avatar.attached? %>
Expand Down
2 changes: 1 addition & 1 deletion config/credentials.yml.enc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2TS6/xwDC3ESz5XJgscb0P89l5mWPtl5KWB5UROa4/sOvR0SOs15MaleH5W/HGfo7JUZxNuQUA8QTdBSyet+di/YCnGTmIhowy8yKLFHFU9JMbZ2dC1QDeAK6enO+sHilOnBuTaUdT+ZurXBk8bQ7vdkUXIz0+eGCdK/6am5MXUjFsIKNdWATVk6XtX9beMuhuayseYKwQmQ3RFve/dDqs1L+W02pjEHqyUBfphQosaSgP4s7HTDYpcD8Wpf2EuykH0wZ6ysuF35992mx1+AfMUFh4PCICon6SsyHxQupVZ8yk8Kg5kD1neyCCMmgKqL/BqpT3nboM8mTJZwRfgku/KfAg86Zf38X1t4hVUs0lKwFXisjW1c5dWuaZhrC67tFw9mig6esJ+O4hRcHB/MNqXkZ2jkkUdXpUB3--tVZXcnKfwd2DuIv1--OOWPJW13GYT9iw6dsaNOGw==
No7aJ089FSsDLm/FrJNjqT5ZymFM8ladxE1tmnbxtlY9L/ABgEteSQ10MXU5bogbk0CUFd/MuTr/puSnhX5N8ycRpjSwyQQl36Aip2UYHI+/XeHJnGSsRHEPfDIiaW88MZrqBUpMy9MlumrpYDGysi/gZC2MuPQXkLagn/1wG1yzLvDQPutnlGzEiw3X83vifMgM/L3Heh26MRTAWuU3yPend46X2oFhscCQJgMxyGz4nq2l4vC7bqbyB45KNDCCHgGAr+e60HwFL5zw6gzy61Pvc4W7HU7xbWMTIbvJQxB6eKd6mKoX213h9ISKR0iAEubDUvypCwfZJFWp9nvkL5r5LIQDmPEHciSO0zTkkOmLMfHrJCNTKvFrJHDvk4ABiJ+dAUASMABhv5tb+5IlehyqTegz--/ADGHrM0sG+xBTr/--PQ23CJC9MvxeK3tUBYKU1g==
1 change: 1 addition & 0 deletions config/credentials/development.yml.enc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
9ikLlw2pDypEjirE6xpnyRnM1N6FEK0AfaWOuSZ30RoXa+I+Dr5sP4xNB/EjQWLMVvNxUyc9eCZmDj3FDyzmqbfRtBRSiWXfhUHn7EYyLTvLBn3f1BUrtYYmhLE4Da50d6nBFRCe5eegQXAzviA2nTxic7yZDeoZc3btrMJAhcXOkktWDvSuVD9evWPWWV/UaktCy92NhEc0Df5eFyWH5tkQIzXrXQq1R6uTUS7lX+d2EcNivV9ttfmhA1EHZwU5zPeRKSuEXpZhVCyx+tIo49QSABTO09kAvI6xr0fALvXEq4+X--8pCTVasD9aOEmkv6--y7GHvpFVZkZJktriXSA+ZA==
2 changes: 1 addition & 1 deletion config/environments/production.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
# config.action_cable.allowed_request_origins = [ "http://example.com", /http:\/\/example.*/ ]

# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
# config.force_ssl = true
config.force_ssl = true

# Include generic and useful information about system operation, but avoid logging too much
# information to avoid inadvertent exposure of personally identifiable information (PII).
Expand Down
7 changes: 7 additions & 0 deletions config/initializers/omniauth.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Rails.application.config.middleware.use OmniAuth::Builder do
if Rails.env.production?
provider :google_oauth2, ENV['GOOGLE_CLIENT_ID'], ENV['GOOGLE_CLIENT_SECRET']
else
provider :google_oauth2, Rails.application.credentials.google[:client_id], Rails.application.credentials.google[:client_secret]
end
end
3 changes: 3 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
delete "logout", to: "sessions#destroy"
get "login", to: "sessions#new"

# Google OAuth routes
get "/auth/:provider/callback", to:"sessions#omniauth"

# Password routes
resources :passwords, only: [:create, :edit, :new, :update], param: :password_reset_token

Expand Down
9 changes: 9 additions & 0 deletions db/migrate/20220607232424_add_uid_and_provider_to_users.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class AddUidAndProviderToUsers < ActiveRecord::Migration[7.0]
def change
add_column :users, :uid, :string
add_column :users, :provider, :string

add_index :users, :uid, unique: true
add_index :users, :provider
end
end
6 changes: 5 additions & 1 deletion db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 5682fc7

Please sign in to comment.