Merge pull request #57 from abf/rosa-build:30-social-login-and-open-registration

[refs #30]: Social login and open registration
This commit is contained in:
warpc 2013-04-10 16:52:50 +04:00
commit 0f95623470
20 changed files with 183 additions and 67 deletions

View File

@ -5,9 +5,12 @@ gem 'redhillonrails_core', :git => 'git://github.com/warpc/redhillonrails_core.g
gem 'pg', '~> 0.14.0'
gem 'devise', '~> 2.1.2'
gem 'omniauth', '~> 1.1.0'
gem 'omniauth-openid', '~> 1.0.1'
gem 'devise', '~> 2.2.3'
gem 'omniauth'
gem 'omniauth-facebook'
gem 'omniauth-google-oauth2'
gem 'omniauth-github'
# gem 'omniauth-openid', '~> 1.0.1'
gem 'cancan', '1.6.7' # 1.6.8 fail specs with strange error
gem 'ancestry', '~> 1.3.0'

View File

@ -52,7 +52,7 @@ GEM
activesupport (3.2.13)
i18n (= 0.6.1)
multi_json (~> 1.0)
airbrake (3.1.8)
airbrake (3.1.9)
activesupport
builder
json
@ -68,8 +68,8 @@ GEM
daemons (~> 1.1.4)
i18n (>= 0.5.0)
state_machine (~> 1.1.0)
bourne (1.2.1)
mocha (= 0.12.7)
bourne (1.4.0)
mocha (~> 0.13.2)
builder (3.0.4)
cancan (1.6.7)
cape (1.7.0)
@ -80,7 +80,7 @@ GEM
net-ssh (>= 2.0.14)
net-ssh-gateway (>= 1.1.0)
capistrano_colors (0.5.5)
charlock_holmes (0.6.9.1)
charlock_holmes (0.6.9.2)
chronic (0.6.7)
chunky_png (1.2.7)
cocaine (0.4.2)
@ -90,7 +90,7 @@ GEM
coffee-script (2.2.0)
coffee-script-source
execjs
coffee-script-source (1.6.1)
coffee-script-source (1.6.2)
compass (0.12.2)
chunky_png (~> 1.2)
fssm (>= 0.2.7)
@ -99,7 +99,7 @@ GEM
compass (>= 0.12.2, < 0.14)
creole (0.5.0)
daemons (1.1.9)
devise (2.1.3)
devise (2.2.3)
bcrypt-ruby (~> 3.0)
orm_adapter (~> 0.1)
railties (~> 3.1)
@ -119,6 +119,8 @@ GEM
factory_girl_rails (4.0.0)
factory_girl (~> 4.0.0)
railties (>= 3.0.0)
faraday (0.8.7)
multipart-post (~> 1.1)
ffi (1.0.11)
fssm (0.2.10)
gemoji (1.2.1)
@ -148,9 +150,10 @@ GEM
haml (~> 3.1)
railties (>= 3.1, < 4.1)
hashie (1.2.0)
highline (1.6.16)
highline (1.6.15)
hike (1.2.1)
hirb (0.7.1)
httpauth (0.2.0)
i18n (0.6.1)
jbuilder (0.8.3)
activesupport (>= 3.0.0)
@ -159,6 +162,8 @@ GEM
railties (>= 3.1.0, < 5.0)
thor (~> 0.14)
json (1.7.7)
jwt (0.1.8)
multi_json (>= 1.5)
kgio (2.8.0)
libv8 (3.3.10.4)
macaddr (1.6.1)
@ -180,10 +185,11 @@ GEM
actionpack
metaclass (0.0.1)
mime-types (1.21)
mocha (0.12.7)
mocha (0.13.3)
metaclass (~> 0.0.1)
mock_redis (0.6.2)
multi_json (1.7.1)
multi_json (1.7.2)
multipart-post (1.2.0)
mustache (0.99.4)
net-scp (1.1.0)
net-ssh (>= 2.6.5)
@ -193,13 +199,27 @@ GEM
net-ssh-gateway (1.2.0)
net-ssh (>= 2.6.5)
newrelic_rpm (3.5.5.38)
nokogiri (1.5.7)
nokogiri (1.5.9)
oauth2 (0.8.1)
faraday (~> 0.8)
httpauth (~> 0.1)
jwt (~> 0.1.4)
multi_json (~> 1.0)
rack (~> 1.2)
omniauth (1.1.3)
hashie (~> 1.2)
rack
omniauth-openid (1.0.1)
omniauth-facebook (1.4.1)
omniauth-oauth2 (~> 1.1.0)
omniauth-github (1.1.0)
omniauth (~> 1.0)
omniauth-oauth2 (~> 1.1)
omniauth-google-oauth2 (0.1.13)
omniauth (~> 1.0)
omniauth-oauth2
omniauth-oauth2 (1.1.1)
oauth2 (~> 0.8.0)
omniauth (~> 1.0)
rack-openid (~> 1.3.1)
orm_adapter (0.4.0)
paperclip (3.3.1)
activemodel (>= 3.0.0)
@ -219,9 +239,6 @@ GEM
rack (1.4.5)
rack-cache (1.2)
rack (>= 0.4)
rack-openid (1.3.1)
rack (>= 1.1.0)
ruby-openid (>= 2.1.8)
rack-protection (1.5.0)
rack
rack-ssl (1.3.3)
@ -254,7 +271,7 @@ GEM
rdoc (~> 3.4)
thor (>= 0.14.6, < 2.0)
raindrops (0.10.0)
rake (10.0.3)
rake (10.0.4)
rdiscount (2.0.7.1)
rdoc (3.12.2)
json (~> 1.4)
@ -295,7 +312,6 @@ GEM
ruby-haml-js (0.0.3)
execjs
sprockets (>= 2.0.0)
ruby-openid (2.2.3)
rubypython (0.5.3)
blankslate (>= 2.1.2.3)
ffi (~> 1.0.7)
@ -316,9 +332,9 @@ GEM
shoulda-context (~> 1.0, >= 1.0.1)
shoulda-matchers (~> 1.0, >= 1.4.1)
shoulda-context (1.0.2)
shoulda-matchers (1.5.0)
shoulda-matchers (1.5.4)
activesupport (>= 3.0.0)
bourne (~> 1.2.0)
bourne (~> 1.3)
sinatra (1.3.6)
rack (~> 1.4)
rack-protection (~> 1.3)
@ -342,7 +358,7 @@ GEM
eventmachine (>= 0.12.6)
rack (>= 1.0.0)
thor (0.17.0)
tilt (1.3.5)
tilt (1.3.6)
treetop (1.4.12)
polyglot
polyglot (>= 0.3.1)
@ -389,7 +405,7 @@ DEPENDENCIES
coffee-rails (~> 3.2.2)
compass-rails (~> 1.0.3)
creole
devise (~> 2.1.2)
devise (~> 2.2.3)
diff-display (~> 0.0.1)
factory_girl_rails (~> 4.0.0)
gemoji (~> 1.2.1)
@ -406,8 +422,10 @@ DEPENDENCIES
meta-tags (~> 1.2.5)
mock_redis (= 0.6.2)
newrelic_rpm (~> 3.5.5.38)
omniauth (~> 1.1.0)
omniauth-openid (~> 1.0.1)
omniauth
omniauth-facebook
omniauth-github
omniauth-google-oauth2
paperclip (~> 3.3.1)
perform_later (~> 1.3.0)
pg (~> 0.14.0)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -1,3 +1,16 @@
@import 'devise/login';
nav a { text-decoration: none;}
nav a { text-decoration: none;}
article {
height: auto;
width: 270px;
padding-bottom: 10px;
a {
text-decoration: none;
}
.facebook {
margin-right: -4px;
}
}

View File

@ -21,3 +21,28 @@ div.error.forgot {
div.error.reset {
margin-top: -141px;
margin-left: 645px; }
article {
height: auto;
padding-bottom: 10px;
.hr {
margin-top: 10px;
border-bottom: 1px solid #264862;
border-top: 1px solid #264862;
height: 1px;
}
a {
text-decoration: none;
}
.facebook {
margin-right: -4px;
}
.other {
.left {
margin-top: 6px;
}
.right {
margin-top: 13px;
}
}
}

View File

@ -1,30 +1,64 @@
# -*- encoding : utf-8 -*-
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def open_id
# raise env['omniauth.auth'].inspect
generic
def facebook
oauthorize 'Facebook'
end
def google_oauth2
oauthorize 'google_oauth2'
end
def github
oauthorize 'GitHub'
end
def passthru
render :file => "#{Rails.root}/public/404.html", :status => 404, :layout => false
end
private
protected
def generic
authentication = Authentication.find_or_initialize_by_provider_and_uid(env['omniauth.auth']['provider'], env['omniauth.auth']['uid'])
def oauthorize(kind)
provider = kind.downcase
@user = find_for_ouath(env["omniauth.auth"], current_user)
if @user && @user.persisted?
flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => action_name.classify
sign_in_and_redirect @user, :event => :authentication
else
session["devise.#{provider}_data"] = env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
def find_for_ouath(auth, resource=nil)
provider, uid = auth['provider'], auth['uid']
authentication = Authentication.find_or_initialize_by_provider_and_uid(provider, uid)
if authentication.new_record?
if user_signed_in? # New authentication method for current_user
authentication.user = current_user
authentication.save
else # Register new user from session
session["devise.omniauth_data"] = env["omniauth.auth"].except('extra')
flash[:notice] = I18n.t "devise.omniauth_callbacks.register"
redirect_to new_user_registration_url
case provider
when 'facebook'
name = auth['extra']['raw_info']['name']
when 'google_oauth2', 'github'
name = auth['info']['nickname'] || auth['info']['name']
else
raise 'Provider #{provider} not handled'
end
user = User.find_or_initialize_by_email(auth['info']['email'])
if user.new_record?
user.name = name
user.uname = name.gsub(/\s/, '').underscore
user.password = Devise.friendly_token[0,20]
user.confirmed_at = Time.zone.now
user.save
end
authentication.user = user
end
else
flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => action_name.classify
sign_in_and_redirect authentication.user, :event => :authentication
authentication.save
end
return authentication.user
end
end
end

View File

@ -4,7 +4,11 @@ class Users::RegisterRequestsController < ApplicationController
layout 'invite'
def new
render :invite
if APP_CONFIG['preregistration']
render :invite
else
redirect_to new_user_registration_path
end
end
def create

View File

@ -2,6 +2,6 @@
class Authentication < ActiveRecord::Base
belongs_to :user
validates :provider, :uid, :presence => true
validates :provider, :uid, :user_id, :presence => true
validates :uid, :uniqueness => {:scope => :provider, :case_sensitive => false}
end

View File

@ -7,6 +7,7 @@ class User < Avatar
devise :database_authenticatable, :registerable, :omniauthable, :token_authenticatable,# :encryptable, :timeoutable
:recoverable, :rememberable, :validatable, :lockable, :confirmable#, :reconfirmable, :trackable
devise :omniauthable, :omniauth_providers => [:facebook, :google_oauth2, :github]
has_one :notifier, :class_name => 'SettingsNotifier', :dependent => :destroy #:notifier
@ -98,20 +99,6 @@ class User < Avatar
{ :value => login.downcase, :orig_value => login }]).first
end
def new_with_session(params, session)
super.tap do |user|
if data = session["devise.omniauth_data"]
if info = data['info'] and info.present?
user.email = info['email'].presence if user.email.blank?
user.uname ||= info['nickname'].presence || info['username'].presence
user.name ||= info['name'].presence || [info['first_name'], info['last_name']].join(' ').strip
end
user.password = Devise.friendly_token[0,20] # stub password
user.authentications.build :uid => data['uid'], :provider => data['provider']
end
end
end
def auth_by_token_or_login_pass(user, pass)
u = User.find_for_database_authentication(:login => user)
u if u && !u.access_locked? && (u.authentication_token == user || u.valid_password?(pass))

View File

@ -17,7 +17,10 @@
.both
.left=t('activerecord.attributes.user.email')
.right
= f.text_field :email, :id => 'email', :readonly => 'readonly', :class => "registartion-input #{email_error ? 'registartion-input-error' : ''}"
- if APP_CONFIG['preregistration']
= f.text_field :email, :id => 'email', :readonly => 'readonly', :class => "registartion-input #{email_error ? 'registartion-input-error' : ''}"
- else
= f.text_field :email, :id => 'email', :class => 'registartion-input'
.both
.left=t('activerecord.attributes.user.password')
.right
@ -30,6 +33,7 @@
.in
=f.submit t("layout.devise.shared_links.sign_up"), :class => 'button', :id => 'btnLogin'
.both
= render 'devise/shared/providers'
=showDeviseHintError(:login, uname_error)
=showDeviseHintError(:name, name_error)

View File

@ -27,8 +27,7 @@
.text=t('devise.sessions.remember_me')
.in=f.submit t('layout.devise.shared_links.sign_in'), :class => 'button', :id => 'btnLogin'
%div{:style => "clear: both;"}
.hr
.both
= render 'devise/shared/providers'
.forgot
.password
%p= link_to t("layout.devise.shared_links.forgot_password"), new_password_path(resource_name)

View File

@ -0,0 +1,11 @@
- if devise_mapping.omniauthable?
.hr
.other
.left
%p= t('layout.sessions.sign_up_with')
.right
- resource_class.omniauth_providers.each do |provider|
= link_to omniauth_authorize_path(resource_name, provider) do
- provider = provider.to_s.gsub(/_oauth2/,'')
= image_tag("#{provider}.png", :alt => provider, :class => provider)
.both

View File

@ -2,6 +2,7 @@ common: &common
project_name: ABF
repo_project_name: ABF
anonymous_access: true
preregistration: false
file_store_url: 'http://file-store.rosalinux.ru'
distr_types: ['mdv', 'rhel', 'nau5']
abf_worker:
@ -11,6 +12,15 @@ common: &common
airbrake_api_key: 'airbrake_api_key'
devise_pepper: 'devise_pepper'
secret_token: 'secret_token'
github:
id: 'APP_ID'
secret: 'APP_SECRET'
google:
id: 'APP_ID'
secret: 'APP_SECRET'
facebook:
id: 'APP_ID'
secret: 'APP_SECRET'
wiki_formats:
markdown: "Markdown"

View File

@ -188,8 +188,13 @@ Devise.setup do |config|
# Add a new OmniAuth provider. Check the wiki for more information on setting
# up on your models and hooks.
# config.omniauth :github, 'APP_ID', 'APP_SECRET', :scope => 'user,public_repo'
require 'openid/store/filesystem'
config.omniauth :openid, :name => 'open_id' #, :store => OpenID::Store::Filesystem.new('./tmp')
# require 'openid/store/filesystem'
# config.omniauth :openid, :name => 'open_id' #, :store => OpenID::Store::Filesystem.new('./tmp')
config.omniauth :facebook, APP_CONFIG['keys']['facebook']['id'], APP_CONFIG['keys']['facebook']['secret']
config.omniauth :google_oauth2, APP_CONFIG['keys']['google']['id'], APP_CONFIG['keys']['google']['secret'], {:access_type => 'offline', :approval_prompt => ''}
config.omniauth :github, APP_CONFIG['keys']['github']['id'], APP_CONFIG['keys']['github']['secret'], {:scope => 'user:email'}
# ==> Warden configuration
# If you want to use other strategies, that are not supported by Devise, or

View File

@ -0,0 +1 @@
OmniAuth.config.logger = Rails.logger

View File

@ -87,6 +87,7 @@ en:
sessions:
sign_in_header: Sign in
sign_up_with: "Sign up with:"
private_users:
list: List

View File

@ -87,6 +87,7 @@ ru:
sessions:
sign_in_header: Вход в систему
sign_up_with: "Зарегистрироваться с:"
private_users:
list: Список

View File

@ -51,10 +51,10 @@ module Preregistration
end
end
end #RegistrationsController
end #Devise
end #Preregistration
end # RegistrationsController
end # Devise
end # Preregistration
Rails.application.config.to_prepare do
::Devise::RegistrationsController.send :include, Preregistration::Devise::RegistrationsController
::Devise::RegistrationsController.send :include, Preregistration::Devise::RegistrationsController if APP_CONFIG['preregistration']
end