Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
99e525c
WIP Facebook OAuth
smartlime Aug 22, 2016
480d66e
User model spec, User.find_for_oauth method
smartlime Aug 23, 2016
f85e9ae
Add Twitter in callbacks controller
smartlime Aug 23, 2016
cfc6b6d
Add Identity model validations and specs
smartlime Aug 23, 2016
d7fbdce
bundle update to avoid deprecation warnings
smartlime Aug 25, 2016
5df4c6e
WIP Feature spec for OAuth login
smartlime Aug 25, 2016
e188fc1
Fix typo in spec
smartlime Aug 28, 2016
1b33465
Add circle.yml to fix broken defaults of CircleCI
smartlime Aug 28, 2016
25e7ac6
Switch Ruby Version to 2.3.1 explicitly
smartlime Aug 29, 2016
b77f6f6
Try to downgrade Ruby to 2.3.0 for CircleCI only
smartlime Aug 29, 2016
1033b6f
Daemonize rackup in bin/comet
smartlime Aug 29, 2016
b44f65a
One more fix ix circle.yml
smartlime Aug 29, 2016
f307147
Add :confirmable to Users (reconfigure Devise)
smartlime Aug 29, 2016
1d1e9d1
Add and configure 'letter_opener' and 'capybara-email' gems
smartlime Aug 29, 2016
958a16e
Add Twitter API keys
smartlime Aug 31, 2016
e3abd40
Create stub spec for Account controller for email confirmation
smartlime Sep 2, 2016
03e5db7
Add routes to confirm email using Account controller
smartlime Sep 2, 2016
f65c978
Downgrade sprockets gem to 3.6.3 to avoid pesky deprication warning i…
smartlime Sep 2, 2016
ea1c0c0
Email confirmation template in draft
smartlime Sep 2, 2016
d01a3c0
Add set_flash method
smartlime Sep 5, 2016
4a9c089
Minor model changes
smartlime Sep 5, 2016
4b315d7
Change originator email to e@varnakov.ru
smartlime Sep 5, 2016
4a13d8f
Identity factory change to work with sequences
smartlime Sep 6, 2016
57e6c19
Accounts controller (to confirm email) w/spec
smartlime Sep 6, 2016
bc9c1b5
Draft of omniauth_callbacks controller w/spec
smartlime Sep 6, 2016
b09b26e
Fix configuration to correct handling of emails at test env
smartlime Sep 6, 2016
34e6f71
Fix Identity model spec; Make it comaptible with case-sensitive valid…
smartlime Sep 6, 2016
bbecfa7
Temporary feature spec for OAuth sign in
smartlime Sep 6, 2016
b0bde33
Cleanup omniauth_macros.rb
smartlime Sep 6, 2016
d31f6e8
Add real email validation route
smartlime Sep 6, 2016
eeb30a6
Add display of email validation errors, fix parameter name
smartlime Sep 6, 2016
0f728f8
Add Twitter OAuth to Devise config
smartlime Sep 6, 2016
2114cd1
OAuth sign in feature spec; many fixes
smartlime Sep 6, 2016
d421fcf
More DRY OAuth sign in spec
smartlime Sep 6, 2016
a5d4434
Try to check emails in specs
smartlime Sep 6, 2016
f3d2ad7
Temporary disable checks in confirm registration spec
smartlime Sep 7, 2016
71d59ad
Still trying to check mails in RSpec. With no luck yet.
smartlime Sep 10, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .ruby-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ruby-2.3-head
ruby-2.3.1
8 changes: 8 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ source 'https://rubygems.org'

gem 'rails', '4.2.6'
gem 'pg', '~> 0.15'
gem 'sprockets', '3.6.3'
gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.1.0'
Expand All @@ -22,6 +23,9 @@ gem 'private_pub'
gem 'skim'
gem 'gon'
gem 'responders'
gem 'omniauth'
gem 'omniauth-facebook'
gem 'omniauth-twitter'

# gem 'unicorn'
gem 'thin'
Expand All @@ -43,6 +47,8 @@ group :test do
gem 'capybara-webkit'
end

gem 'capybara-email'

group :development do
gem 'web-console', '~> 2.0'
gem 'pry'
Expand All @@ -57,4 +63,6 @@ group :development do
gem 'rails_best_practices'

gem 'spring'

gem 'letter_opener'
end
66 changes: 52 additions & 14 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ GEM
addressable (2.4.0)
arel (6.0.3)
ast (2.3.0)
autoprefixer-rails (6.3.7)
autoprefixer-rails (6.4.0.3)
execjs
bcrypt (3.1.11)
better_errors (2.1.1)
Expand All @@ -61,6 +61,9 @@ GEM
rack (>= 1.0.0)
rack-test (>= 0.5.4)
xpath (~> 2.0)
capybara-email (2.5.0)
capybara (~> 2.4)
mail
capybara-webkit (1.11.1)
capybara (>= 2.3.0, < 2.8.0)
json
Expand All @@ -71,7 +74,7 @@ GEM
mime-types (>= 1.16)
mimemagic (>= 0.3.0)
cocoon (1.2.9)
code_analyzer (0.4.5)
code_analyzer (0.4.7)
sexp_processor
coderay (1.1.1)
coffee-rails (4.1.1)
Expand All @@ -83,7 +86,7 @@ GEM
coffee-script-source (1.10.0)
concurrent-ruby (1.0.2)
cookiejar (0.3.3)
daemons (1.2.3)
daemons (1.2.4)
database_cleaner (1.5.3)
debug_inspector (0.0.2)
devise (4.2.0)
Expand Down Expand Up @@ -111,6 +114,8 @@ GEM
railties (>= 3.0.0)
faker (1.6.6)
i18n (~> 0.5)
faraday (0.9.2)
multipart-post (>= 1.2, < 3)
faye (1.2.2)
cookiejar (>= 0.3.0)
em-http-request (>= 0.3.0)
Expand Down Expand Up @@ -142,22 +147,26 @@ GEM
shellany (~> 0.0)
thor (>= 0.18.1)
guard-compat (1.2.1)
guard-rspec (4.7.2)
guard-rspec (4.7.3)
guard (~> 2.1)
guard-compat (~> 1.1)
rspec (>= 2.99.0, < 4.0)
hashie (3.4.4)
http_parser.rb (0.6.0)
i18n (0.7.0)
jbuilder (2.6.0)
activesupport (>= 3.0.0, < 5.1)
multi_json (~> 1.2)
jquery-rails (4.1.1)
jquery-rails (4.2.1)
rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
json (1.8.3)
jwt (1.5.4)
launchy (2.4.3)
addressable (~> 2.3)
letter_opener (1.4.1)
launchy (~> 2.2)
listen (3.1.5)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
Expand All @@ -175,17 +184,40 @@ GEM
mime-types (3.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2016.0521)
mimemagic (0.3.1)
mimemagic (0.3.2)
mini_portile2 (2.1.0)
minitest (5.9.0)
multi_json (1.12.1)
multi_xml (0.5.5)
multipart-post (2.0.0)
nenv (0.3.0)
nokogiri (1.6.8)
mini_portile2 (~> 2.1.0)
pkg-config (~> 1.1.7)
notiffany (0.1.0)
notiffany (0.1.1)
nenv (~> 0.1)
shellany (~> 0.0)
oauth (0.5.1)
oauth2 (1.2.0)
faraday (>= 0.8, < 0.10)
jwt (~> 1.0)
multi_json (~> 1.3)
multi_xml (~> 0.5)
rack (>= 1.2, < 3)
omniauth (1.3.1)
hashie (>= 1.2, < 4)
rack (>= 1.0, < 3)
omniauth-facebook (4.0.0)
omniauth-oauth2 (~> 1.2)
omniauth-oauth (1.1.0)
oauth
omniauth (~> 1.0)
omniauth-oauth2 (1.4.0)
oauth2 (~> 1.0)
omniauth (~> 1.2)
omniauth-twitter (1.2.1)
json (~> 1.3)
omniauth-oauth (~> 1.1)
orm_adapter (0.5.0)
parser (2.3.1.2)
ast (~> 2.2)
Expand Down Expand Up @@ -253,21 +285,21 @@ GEM
remotipart (1.2.1)
request_store (1.3.1)
require_all (1.3.3)
responders (2.2.0)
responders (2.3.0)
railties (>= 4.2.0, < 5.1)
rspec (3.5.0)
rspec-core (~> 3.5.0)
rspec-expectations (~> 3.5.0)
rspec-mocks (~> 3.5.0)
rspec-core (3.5.1)
rspec-core (3.5.2)
rspec-support (~> 3.5.0)
rspec-expectations (3.5.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.5.0)
rspec-mocks (3.5.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.5.0)
rspec-rails (3.5.1)
rspec-rails (3.5.2)
actionpack (>= 3.0)
activesupport (>= 3.0)
railties (>= 3.0)
Expand All @@ -283,7 +315,7 @@ GEM
ruby-progressbar (~> 1.7)
unicode-display_width (~> 1.0, >= 1.0.1)
ruby-progressbar (1.8.1)
ruby_dep (1.3.1)
ruby_dep (1.4.0)
sass (3.4.22)
sass-rails (5.0.6)
railties (>= 4.0.0, < 6)
Expand Down Expand Up @@ -314,7 +346,7 @@ GEM
spring (1.7.2)
spring-commands-rspec (1.0.4)
spring (>= 0.9.1)
sprockets (3.7.0)
sprockets (3.6.3)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
sprockets-rails (3.1.1)
Expand All @@ -329,12 +361,12 @@ GEM
thor (0.19.1)
thread_safe (0.3.5)
tilt (2.0.5)
turbolinks (5.0.0)
turbolinks (5.0.1)
turbolinks-source (~> 5)
turbolinks-source (5.0.0)
tzinfo (1.2.2)
thread_safe (~> 0.1)
uglifier (3.0.0)
uglifier (3.0.2)
execjs (>= 0.3.0, < 3)
unicode-display_width (1.1.0)
warden (1.2.6)
Expand All @@ -359,6 +391,7 @@ DEPENDENCIES
bootstrap-sass (~> 3.3.6)
byebug (~> 8.0)
capybara
capybara-email
capybara-webkit
carrierwave
cocoon
Expand All @@ -372,7 +405,11 @@ DEPENDENCIES
jbuilder (~> 2.0)
jquery-rails
launchy
letter_opener
meta_request
omniauth
omniauth-facebook
omniauth-twitter
pg (~> 0.15)
private_pub
pry
Expand All @@ -393,6 +430,7 @@ DEPENDENCIES
slim-rails
spring
spring-commands-rspec
sprockets (= 3.6.3)
thin
turbolinks
uglifier (>= 1.3.0)
Expand Down
47 changes: 47 additions & 0 deletions app/controllers/account_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
class AccountController < ApplicationController
before_action :check_already_signed_in, only: [:confirm_email]
before_action :check_oauth_in_session, only: [:confirm_email]

def confirm_email
if request.patch?
email = nil
email = params[:user][:email] if params[:user] && params[:user][:email]
user = User.where(email: email).first
provider = session['devise.oauth_provider']
if user.present?
set_flash :alert, 'Email already taken.'
else
User.transaction do
@user = User.create(email: email, password: Devise.friendly_token[0, 20])
if @user.persisted?
@user.identities.create!({
provider: provider,
uid: session['devise.oauth_uid'].to_s})
end
end
if @user.persisted?
set_flash :notice, t('devise.omniauth_callbacks.success', kind: provider.to_s.capitalize)
sign_in_and_redirect @user, event: :authentication
end
end
end
end

private

def check_already_signed_in
redirect_to questions_path if signed_in?
end

def check_oauth_in_session
if !session['devise.oauth_provider'] && !session['devise.oauth_uid']
set_flash :notice, 'Registration done'
redirect_to questions_path
elsif !session['devise.oauth_provider'] || !session['devise.oauth_uid']
session['devise.oauth_provider'] = nil
session['devise.oauth_uid'] = nil
set_flash :alert, 'Authentication error, try again'
redirect_to new_user_session_path
end
end
end
6 changes: 6 additions & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ class ApplicationController < ActionController::Base

before_action :set_js_current_user

protected

def set_flash(scope, message)
flash[scope] = message if is_navigational_format?
end

private

def set_js_current_user
Expand Down
43 changes: 43 additions & 0 deletions app/controllers/omniauth_callbacks_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
before_action :oauth

def facebook
end

def twitter
end

private

def oauth
email = nil
email = params[:user][:email] if params[:user] && params[:user][:email]
auth = request.env['omniauth.auth'] || OmniAuth::AuthHash.new(
provider: session['oauth_provider'],
uid: session['oauth_uid'],
info: {email: email})
if auth
@user = User.find_for_oauth(auth)
if @user.nil? && auth && auth.provider && auth.uid
store_auth auth
redirect_to account_confirm_email_path
elsif @user&.persisted?
set_flash_message :notice, :success, kind: auth.provider.to_s.capitalize if is_navigational_format?
sign_in_and_redirect @user, event: :authentication
else
failure_redirect
end
else
failure_redirect
end
end

def store_auth(auth)
session['devise.oauth_provider'] = auth.provider
session['devise.oauth_uid'] = auth.uid
end

def failure_redirect
redirect_to new_user_registration_path, alert: 'Authentication failure'
end
end
6 changes: 6 additions & 0 deletions app/models/identity.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class Identity < ActiveRecord::Base
belongs_to :user

validates :user_id, :provider, presence: true
validates :uid, presence: true, uniqueness: {scope: :provider}
end
27 changes: 26 additions & 1 deletion app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,34 @@ class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
:recoverable, :rememberable, :trackable, :validatable,
:confirmable,
:omniauthable, omniauth_providers: [:facebook, :twitter]

has_many :identities, dependent: :destroy
has_many :questions, dependent: :destroy
has_many :answers, dependent: :destroy
has_many :comments, dependent: :destroy

class << self
def find_for_oauth(auth)
return nil unless auth

identity = Identity.where(provider: auth.provider, uid: auth.uid.to_s).first
return identity.user if identity

email = auth.info[:email] if auth.info
return nil unless email

user = User.where(email: email).first
unless user
password = Devise.friendly_token(20)
user = User.new(email: email, password: password, password_confirmation: password)
user.save
end

user.identities.create(provider: auth.provider, uid: auth.uid) if user
user
end
end
end
Loading