Skip to content

Commit

Permalink
Improve OAuth login
Browse files Browse the repository at this point in the history
  • Loading branch information
jcraigk committed Dec 11, 2024
1 parent 07a2178 commit ff2130c
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 11 deletions.
46 changes: 38 additions & 8 deletions app/controllers/oauth/sorcery_controller.rb
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
require "typhoeus"

class Oauth::SorceryController < ApplicationController
def login
login_at(params[:provider])
end

def callback
user = login_from(params[:provider], true) || create_from(params[:provider])
provider = params[:provider]
auth = build_auth_hash(provider)
user = User.where(email: auth[:email]).first_or_initialize
user.save! unless user.persisted?

user.authentications.where(provider:).first_or_create! do |authentication|
authentication.uid = auth[:uid]
end

reset_session
store_user_data_in_session(user)
redirect_to root_path
rescue ActiveRecord::RecordNotUnique
redirect_to root_path, alert: "That email address has already been taken"
rescue StandardError => e
Sentry.capture_exception(e)
redirect_to root_path, alert: "Login via Google failed"
redirect_to root_path, alert: "Login with Google failed"
end

private
Expand All @@ -23,10 +32,6 @@ def store_user_data_in_session(user)
session[:email] = user.email
end

def provider_title
params[:provider].titleize
end

def jwt_for(user)
JWT.encode(
{
Expand All @@ -37,4 +42,29 @@ def jwt_for(user)
"HS256"
)
end

def build_auth_hash(provider)
response = Typhoeus.get \
"https://www.googleapis.com/oauth2/v2/userinfo",
headers: { Authorization: "Bearer #{fetch_access_token}" }
data = JSON.parse(response.body)
{
uid: data["id"],
email: data["email"]
}
end

def fetch_access_token
response = Typhoeus.post(
"https://oauth2.googleapis.com/token",
body: {
code: params[:code],
client_id: Rails.application.config.sorcery.google.key,
client_secret: Rails.application.config.sorcery.google.secret,
redirect_uri: Rails.application.config.sorcery.google.callback_url,
grant_type: "authorization_code"
}
)
JSON.parse(response.body)["access_token"]
end
end
2 changes: 2 additions & 0 deletions app/javascript/stylesheets/feedback.css.scss
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
font-size: 1.4rem;
width: 20rem;
animation: popOut 0.3s ease-in-out;
overflow: hidden;

&.notice {
background-color: $bg-blue;
Expand All @@ -44,6 +45,7 @@
height: 4px;
background-color: $header-gray;
animation: progress 5s linear forwards;
// margin: 0 -1rem -1rem -1rem;
}
}

Expand Down
6 changes: 3 additions & 3 deletions app/models/concerns/sorcery_authenticable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ module SorceryAuthenticable
presence: true,
uniqueness: true,
format: {
with: /\A[A-Za-z0-9_]{4,15}\z/,
with: /\A[A-Za-z0-9_]{3,15}\z/,
message: "may contain only letters, numbers, and " \
"underscores, must be unique, and must be " \
"4 to 15 characters long"
"3 to 15 characters long"
}
validates :email, uniqueness: true, format: { with: URI::MailTo::EMAIL_REGEXP }
validates :password, length: { minimum: 5 }, if: :password
Expand All @@ -30,7 +30,7 @@ def assign_username_from_email

name = email.split("@").first.gsub(/[^A-Za-z0-9_]/, "_")
name = "#{name.first(10)}_#{SecureRandom.hex(2)}" if User.where(username: name).exists?
self.username = name
self.username = name.first(15)
end
end
end

0 comments on commit ff2130c

Please sign in to comment.