Commit e7ae2545 authored by Braulio Bhavamitra's avatar Braulio Bhavamitra
Browse files

oauth_client: deserialize fields and improve authentication

parent c5776ba3
......@@ -4,8 +4,8 @@ class OauthClientPluginPublicController < PublicController
def callback
auth = request.env["omniauth.auth"]
user = environment.users.find_by_email(auth.info.email)
user ? login(user) : signup(auth)
auth_user = environment.users.where(email: auth.info.email).first
if auth_user then login auth_user.person else signup auth end
end
def failure
......@@ -20,16 +20,14 @@ class OauthClientPluginPublicController < PublicController
protected
def login(user)
def login person
provider = OauthClientPlugin::Provider.find(session[:provider_id])
user_provider = user.oauth_user_providers.find_by_provider_id(provider.id)
unless user_provider
user_provider = user.oauth_user_providers.create(:user => user, :provider => provider, :enabled => true)
end
if user_provider.enabled? && provider.enabled?
session[:user] = user.id
auth = person.oauth_auths.where(provider_id: provider.id).first
auth ||= person.oauth_auths.create! profile: person, provider: provider, enabled: true
if auth.enabled? && provider.enabled?
self.current_user = person.user
else
session[:notice] = _("Can't login with %s") % provider.name
session[:notice] = _("Can't login with #{provider.name}")
end
redirect_to :controller => :account, :action => :login
......
class DeserializeFieldsOnOauthClientPluginProvider < ActiveRecord::Migration
def up
add_column :oauth_client_plugin_providers, :client_id, :text
add_column :oauth_client_plugin_providers, :client_secret, :text
OauthClientPlugin::Provider.find_each batch_size: 50 do |provider|
provider.client_id = provider.options.delete :client_id
provider.client_secret = provider.options.delete :client_secret
provider.save!
end
add_index :oauth_client_plugin_providers, :client_id
end
def down
say "this migration can't be reverted"
end
end
class AddAuthorizationDataToOauthClientUserProvider < ActiveRecord::Migration
def change
rename_table :oauth_client_plugin_user_providers, :oauth_client_plugin_auths
add_column :oauth_client_plugin_auths, :type, :string
add_column :oauth_client_plugin_auths, :provider_user_id, :string
add_column :oauth_client_plugin_auths, :access_token, :text
add_column :oauth_client_plugin_auths, :expires_at, :datetime
add_column :oauth_client_plugin_auths, :scope, :text
add_column :oauth_client_plugin_auths, :data, :text, default: {}.to_yaml
add_column :oauth_client_plugin_auths, :profile_id, :integer
OauthClientPlugin::Auth.find_each batch_size: 50 do |auth|
auth.profile = User.find(auth.user_id).person
auth.save!
end
remove_column :oauth_client_plugin_auths, :user_id
add_index :oauth_client_plugin_auths, :profile_id
add_index :oauth_client_plugin_auths, :provider_id
add_index :oauth_client_plugin_auths, :provider_user_id
add_index :oauth_client_plugin_auths, :type
end
end
require_dependency 'profile'
class Profile
has_many :oauth_auths, class_name: 'OauthClientPlugin::Auth', dependent: :destroy
has_many :oauth_providers, through: :oauth_auths, source: :provider
end
......@@ -2,8 +2,14 @@ require_dependency 'user'
class User
has_many :oauth_user_providers, :class_name => 'OauthClientPlugin::UserProvider'
has_many :oauth_providers, :through => :oauth_user_providers, :source => :provider
has_many :oauth_auths, through: :person
has_many :oauth_providers, through: :oauth_auths, source: :provider
after_create :activate_oauth_user
def activate_oauth_user
self.activate if oauth_providers.present?
end
def password_required_with_oauth?
password_required_without_oauth? && oauth_providers.empty?
......@@ -11,17 +17,6 @@ class User
alias_method_chain :password_required?, :oauth
after_create :activate_oauth_user
def activate_oauth_user
unless oauth_providers.empty?
activate
oauth_providers.each do |provider|
OauthClientPlugin::UserProvider.create!(:user => self, :provider => provider, :enabled => true)
end
end
end
def make_activation_code_with_oauth
oauth_providers.blank? ? make_activation_code_without_oauth : nil
end
......
......@@ -45,7 +45,9 @@ class OauthClientPlugin < Noosfero::Plugin
true
end
OmniAuth.config.on_failure = OauthClientPluginPublicController.action(:failure)
Rails.configuration.to_prepare do
OmniAuth.config.on_failure = OauthClientPluginPublicController.action(:failure)
end
Rails.application.config.middleware.use OmniAuth::Builder do
PROVIDERS.each do |provider, options|
......@@ -60,7 +62,8 @@ class OauthClientPlugin < Noosfero::Plugin
provider_id = request.params['id']
provider_id ||= request.session['omniauth.params']['id'] if request.session['omniauth.params']
provider = environment.oauth_providers.find(provider_id)
strategy.options.merge!(provider.options.symbolize_keys)
strategy.options.merge! client_id: provider.client_id, client_secret: provider.client_secret
strategy.options.merge! provider.options.symbolize_keys
request.session[:provider_id] = provider_id
}
......
class OauthClientPlugin::Provider < Noosfero::Plugin::ActiveRecord
belongs_to :environment
validates_presence_of :name, :strategy
acts_as_having_image
acts_as_having_settings :field => :options
settings_items :client_id, :type => :string
settings_items :client_secret, :type => :string
settings_items :client_options, :type => Hash
attr_accessible :name, :environment, :strategy, :client_id, :client_secret, :enabled, :client_options, :image_builder
scope :enabled, :conditions => {:enabled => true}
acts_as_having_image
end
class OauthClientPlugin::UserProvider < Noosfero::Plugin::ActiveRecord
belongs_to :user, :class_name => 'User'
belongs_to :provider, :class_name => 'OauthClientPlugin::Provider'
set_table_name :oauth_client_plugin_user_providers
attr_accessible :user, :provider, :enabled
end
class OauthClientPlugin::Auth < ActiveRecord::Base
attr_accessible :profile, :provider, :enabled,
:access_token, :expires_in
belongs_to :profile, class_name: 'Profile'
belongs_to :provider, class_name: 'OauthClientPlugin::Provider'
validates_presence_of :profile
validates_presence_of :provider
validates_uniqueness_of :profile_id, scope: :provider_id
acts_as_having_settings field: :data
def expires_in
self.expires_at - Time.now
end
def expires_in= value
self.expires_at = Time.now + value.to_i
end
def expired?
Time.now > self.expires_at rescue true
end
def not_expired?
not self.expired?
end
end
class OauthClientPlugin::Provider < ActiveRecord::Base
belongs_to :environment
validates_presence_of :name, :strategy
acts_as_having_image
acts_as_having_settings field: :options
settings_items :site, type: String
settings_items :client_options, type: Hash
attr_accessible :name, :strategy, :enabled, :site, :image_builder,
:environment, :environment_id,
:client_id, :client_secret, :client_options
scope :enabled, -> { where enabled: true }
acts_as_having_image
end
require File.dirname(__FILE__) + '/../test_helper'
require 'test_helper'
class OauthClientPluginPublicControllerTest < ActionController::TestCase
......@@ -21,7 +21,7 @@ class OauthClientPluginPublicControllerTest < ActionController::TestCase
end
should 'redirect to login when user is found' do
user = fast_create(User, :environment_id => environment.id)
user = create_user
auth.info.stubs(:email).returns(user.email)
auth.info.stubs(:name).returns(user.name)
session[:provider_id] = provider.id
......@@ -32,7 +32,7 @@ class OauthClientPluginPublicControllerTest < ActionController::TestCase
end
should 'do not login when the provider is disabled' do
user = fast_create(User, :environment_id => environment.id)
user = create_user
auth.info.stubs(:email).returns(user.email)
auth.info.stubs(:name).returns(user.name)
session[:provider_id] = provider.id
......@@ -44,11 +44,11 @@ class OauthClientPluginPublicControllerTest < ActionController::TestCase
end
should 'do not login when the provider is disabled for a user' do
user = fast_create(User, :environment_id => environment.id)
user = create_user
auth.info.stubs(:email).returns(user.email)
auth.info.stubs(:name).returns(user.name)
session[:provider_id] = provider.id
user.oauth_user_providers.create(:user => user, :provider => provider, :enabled => false)
user.person.oauth_auths.create!(profile: user.person, provider: provider, enabled: false)
get :callback
assert_redirected_to :controller => :account, :action => :login
......@@ -56,7 +56,7 @@ class OauthClientPluginPublicControllerTest < ActionController::TestCase
end
should 'save provider when an user login with it' do
user = fast_create(User, :environment_id => environment.id)
user = create_user
auth.info.stubs(:email).returns(user.email)
auth.info.stubs(:name).returns(user.name)
session[:provider_id] = provider.id
......@@ -66,13 +66,13 @@ class OauthClientPluginPublicControllerTest < ActionController::TestCase
end
should 'do not duplicate relations between an user and a provider when the same provider was used again in a login' do
user = fast_create(User, :environment_id => environment.id)
user = create_user
auth.info.stubs(:email).returns(user.email)
auth.info.stubs(:name).returns(user.name)
session[:provider_id] = provider.id
get :callback
assert_no_difference 'user.oauth_user_providers.count' do
assert_no_difference 'user.oauth_auths.count' do
3.times { get :callback }
end
end
......
require File.dirname(__FILE__) + '/../test_helper'
require 'test_helper'
class UserTest < ActiveSupport::TestCase
......
require File.dirname(__FILE__) + '/../test_helper'
require 'test_helper'
class OauthClientPluginTest < ActiveSupport::TestCase
......
require File.dirname(__FILE__) + '/../test_helper'
require 'test_helper'
class UserTest < ActiveSupport::TestCase
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment