Skip to content

Commit 5c6fb38

Browse files
committed
feature/Ensure user name is unique when creating from github oauth
1 parent 276a850 commit 5c6fb38

File tree

2 files changed

+30
-16
lines changed

2 files changed

+30
-16
lines changed
Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
22
# See https://github.com/omniauth/omniauth/wiki/FAQ#rails-session-is-clobbered-after-callback-on-developer-strategy
33
skip_before_action :verify_authenticity_token, only: :github
4+
5+
GITHUB_OMNIAUTH_FAIL_MESSAGE = 'Unable to sign in with Github.'.freeze
46

57
def github
68
@user = User.from_omniauth(request.env["omniauth.auth"])
79

810
if @user.persisted?
911
sign_in_and_redirect @user
1012
else
11-
redirect_to new_user_registration_url(notice: 'Unable to sign in with Github.')
13+
redirect_to new_user_registration_url(notice: GITHUB_OMNIAUTH_FAIL_MESSAGE)
1214
end
1315
end
1416

1517
def failure
16-
redirect_to root_path
18+
redirect_to root_path(notice: GITHUB_OMNIAUTH_FAIL_MESSAGE)
1719
end
1820
end

app/models/user.rb

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class User < ApplicationRecord
3838
#TODO: Add tests for this
3939
after_create :create_default_folder
4040

41-
validates :name, presence: true, length: { maximum: 15 }, format: { with: ALPHANUMERIC }
41+
validates :name, presence: true, uniqueness: true, length: { maximum: 15 }, format: { with: ALPHANUMERIC }
4242
validates :bio, length: { maximum: 160 }
4343
validates :location, length: { maximum: 30 }
4444

@@ -144,32 +144,44 @@ def self.authenticate(params)
144144
end
145145

146146
def self.from_omniauth(auth)
147+
is_new_user = false
148+
147149
user = where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
150+
is_new_user = true
151+
148152
user.email = auth.info.email
149153
user.password = Devise.friendly_token[0, 20]
150-
user.name = auth.info.nickname # assuming the user model has a name
151-
# user.image = auth.info.image # assuming the user model has an image
152-
# If you are using confirmable and the provider(s) you use validate emails,
153-
# uncomment the line below to skip the confirmation emails.
154-
user.skip_confirmation!
154+
user.name = unique_name(parsed_name(auth.info.nickname)) # github display name
155+
user.skip_confirmation! # github already validates emails
155156
end
156-
157-
byebug
158-
159-
if user.persisted?
157+
158+
if is_new_user && user.persisted?
160159
user.attach_avatar_from_omniauth(auth.info.image)
161160
end
162161

163-
byebug
164-
165162
user
166163
end
167164

165+
def self.parsed_name(name)
166+
name.gsub('-', '')
167+
end
168+
169+
def self.unique_name(test_name)
170+
# As we are using this within a create block User.all is scoped
171+
# to the arguments passed to the where clause.
172+
existing_user = User.unscoped.find_by(name: test_name)
173+
174+
if existing_user
175+
unique_name("#{test_name}#{rand(1000)}")
176+
else
177+
test_name
178+
end
179+
end
180+
168181
def attach_avatar_from_omniauth(avatar_url)
169182
begin
170183
image = open(avatar_url)
171-
172-
avatar.attach(io: image, filename: 'whocares')
184+
avatar.attach(io: image, filename: "#{id}_avatar")
173185
rescue
174186
end
175187
end

0 commit comments

Comments
 (0)