@@ -5,6 +5,7 @@ class User < ApplicationRecord
55 :recoverable , :rememberable , :trackable , :confirmable , #:validatable,
66 :omniauthable , omniauth_providers : [ :twitter , :github , :developer ]
77
8+ has_many :identities , dependent : :destroy
89 has_many :invitations , dependent : :destroy
910 has_many :teammates , dependent : :destroy
1011 has_many :reviewer_teammates , -> { where ( role : [ 'reviewer' , 'program team' , 'organizer' ] ) } , class_name : 'Teammate'
@@ -22,7 +23,7 @@ class User < ApplicationRecord
2223 validates :name , presence : true , allow_nil : true
2324 validates_uniqueness_of :email , allow_blank : true
2425 validates_format_of :email , with : Devise . email_regexp , allow_blank : true , if : :email_changed?
25- validates_presence_of :email , on : :create , if : -> { provider . blank? }
26+ validates_presence_of :email , on : :create , if : -> { provider . blank? && identities . blank? }
2627 validates_presence_of :email , on : :update , if : -> { provider . blank? || unconfirmed_email . blank? }
2728 validates_presence_of :password , on : :create
2829 validates_confirmation_of :password , on : :create
@@ -34,17 +35,33 @@ class User < ApplicationRecord
3435
3536 attr_accessor :pending_invite_email
3637
37- def self . from_omniauth ( auth , invitation_email = nil )
38- where ( provider : auth . provider , uid : auth . uid ) . first_or_create do |user |
39- password = Devise . friendly_token [ 0 , 20 ]
40- user . name = auth [ 'info' ] [ 'name' ] if user . name . blank?
41- user . email = invitation_email || auth [ 'info' ] [ 'email' ] || '' if user . email . blank?
42- user . password = password
43- user . password_confirmation = password
44- if !user . confirmed? && invitation_email . present? && user . email == invitation_email
45- user . skip_confirmation!
46- end
38+ def self . from_omniauth ( auth , invitation_email = nil )
39+ # First, lookup in identities table
40+ identity = Identity . find_by ( provider : auth . provider , uid : auth . uid )
41+ return identity . user if identity
42+
43+ # Fall back to legacy lookup in users table
44+ user = find_by ( provider : auth . provider , uid : auth . uid )
45+ return user if user
46+
47+ # Create new user with identity
48+ create_from_omniauth! ( auth , invitation_email )
49+ end
50+
51+ def self . create_from_omniauth! ( auth , invitation_email = nil )
52+ user = new (
53+ name : auth [ 'info' ] [ 'name' ] ,
54+ email : invitation_email || auth [ 'info' ] [ 'email' ] || '' ,
55+ password : ( password = Devise . friendly_token [ 0 , 20 ] ) ,
56+ password_confirmation : password
57+ )
58+ user . identities . build ( provider : auth . provider , uid : auth . uid )
59+
60+ if invitation_email . present? && ( user . email == invitation_email )
61+ user . skip_confirmation!
4762 end
63+
64+ user . tap ( &:save! )
4865 end
4966
5067 def check_pending_invite_email
@@ -66,7 +83,7 @@ def gravatar_hash
6683 end
6784
6885 def connected? ( provider )
69- self . provider == provider
86+ identities . exists? ( provider : provider ) || ( self . provider == provider )
7087 end
7188
7289 def complete?
0 commit comments