Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added api exposure for logging in with an oauth access token. #237

Open
wants to merge 6 commits into
base: 3-1-stable
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
64 changes: 64 additions & 0 deletions app/controllers/spree/api/v1/users_controller_decorator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
module Spree

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style/FrozenStringLiteralComment: Missing magic comment # frozen_string_literal: true.

module Api
module V1
module UsersControllerDecorator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style/Documentation: Missing top-level module documentation comment.


Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Layout/EmptyLinesAroundModuleBody: Extra empty line detected at module body beginning.

def social_login

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Metrics/AbcSize: Assignment Branch Condition size for social_login is too high. [32.95/15]
Metrics/CyclomaticComplexity: Cyclomatic complexity for social_login is too high. [11/6]
Metrics/MethodLength: Method has too many lines. [22/10]
Metrics/PerceivedComplexity: Perceived complexity for social_login is too high. [12/7]

authentication_method = Spree::AuthenticationMethod.find_by_provider(params[:provider])

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Metrics/LineLength: Line is too long. [97/80]

render json: {exception: 'Unsupported provider'}, status: 422 and return unless authentication_method

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Layout/SpaceInsideHashLiteralBraces: Space inside { missing.
Layout/SpaceInsideHashLiteralBraces: Space inside } missing.
Style/AndOr: Use && instead of and.
Metrics/LineLength: Line is too long. [111/80]

omniauth_hash = authentication_method.get_omniauth_hash(params[:oauth_token])

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Metrics/LineLength: Line is too long. [87/80]

authentication = Spree::UserAuthentication.find_by_provider_and_uid(params[:provider], omniauth_hash['uid'])

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Metrics/LineLength: Line is too long. [118/80]


if authentication.present? and authentication.try(:user).present?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style/AndOr: Use && instead of and.

render_user_login(authentication.user)
elsif @current_api_user
@current_api_user.apply_omniauth(omniauth_hash)
@current_api_user.save!
render_user_login(@current_api_user)
else
user = Spree::User.find_by_email(params[:email]) || Spree::User.new
user.apply_omniauth(omniauth_hash)

user.generate_spree_api_key! if user.spree_api_key.blank?

if user.save!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style/IfUnlessModifier: Favor modifier if usage when having a single-line body. Another good alternative is the usage of control flow &&/||.

render_user_login(user)
end
end

if @order

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style/GuardClause: Use a guard clause instead of wrapping the code inside a conditional expression.

user = @current_api_user || authentication.user
@order.associate_user!(user)
end
end

def oauth_providers

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Metrics/MethodLength: Method has too many lines. [11/10]

auth_methods = Spree::AuthenticationMethod.active_authentication_methods

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Metrics/LineLength: Line is too long. [82/80]

auth_methods.map! do |auth_method|
oauth_provider = SpreeSocial::OAUTH_PROVIDERS.detect {|p| p[1] == provider}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Layout/SpaceInsideBlockBraces: Space between { and | missing.
Metrics/LineLength: Line is too long. [87/80]
Layout/SpaceInsideBlockBraces: Space missing inside }.

{
name: oauth_provider[0],

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Layout/IndentHash: Use 2 spaces for indentation in a hash, relative to the start of the line where the left curly brace is.

provider: auth_method.provider,
api_key: auth_method.api_key,
signup_support: oauth_provider[2]
}
end
render json: auth_methods, status: :ok
end

private

def render_user_login(user)
render :json => {:result => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style/HashSyntax: Use the new Ruby 1.9 hash syntax.
Layout/SpaceInsideHashLiteralBraces: Space inside { missing.

:user => "#{user.login}",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Layout/IndentHash: Use 2 spaces for indentation in a hash, relative to the start of the line where the left curly brace is.
Style/HashSyntax: Use the new Ruby 1.9 hash syntax.
Style/UnneededInterpolation: Prefer to_s over string interpolation.

:api_key => "#{user.spree_api_key}",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style/HashSyntax: Use the new Ruby 1.9 hash syntax.
Style/UnneededInterpolation: Prefer to_s over string interpolation.

:user_id => "#{user.id}"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style/HashSyntax: Use the new Ruby 1.9 hash syntax.
Style/UnneededInterpolation: Prefer to_s over string interpolation.

}}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Layout/SpaceInsideHashLiteralBraces: Space inside } missing.

end

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Layout/EmptyLinesAroundModuleBody: Extra empty line detected at module body end.

end
end
end
end

Spree::Api::V1::UsersController.prepend(Spree::Api::V1::UsersControllerDecorator)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Metrics/LineLength: Line is too long. [81/80]
Layout/TrailingBlankLines: Final newline missing.

4 changes: 2 additions & 2 deletions app/controllers/spree/omniauth_callbacks_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class Spree::OmniauthCallbacksController < Devise::OmniauthCallbacksController

def self.provides_callback_for(*providers)
providers.each do |provider|
class_eval <<-FUNCTION_DEFS, __FILE__, __LINE__ + 1
class_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{provider}
if request.env['omniauth.error'].present?
flash[:error] = I18n.t('devise.omniauth_callbacks.failure', kind: auth_hash['provider'], reason: Spree.t(:user_was_not_valid))
Expand Down Expand Up @@ -44,7 +44,7 @@ def #{provider}
session[:guest_token] = nil
end
end
FUNCTION_DEFS
RUBY
end
end

Expand Down
40 changes: 38 additions & 2 deletions app/models/spree/authentication_method.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,49 @@
class Spree::AuthenticationMethod < ActiveRecord::Base
validates :provider, :api_key, :api_secret, presence: true

validate :provider_must_be_backed_by_omniauth_strategy

def self.active_authentication_methods
where(environment: ::Rails.env, active: true)
end

def self.active_authentication_methods?
where(environment: ::Rails.env, active: true).exists?
active_authentication_methods.exists?
end

scope :available_for, lambda { |user|
scope :available_for, lambda {|user|

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Layout/SpaceInsideBlockBraces: Space between { and | missing.

sc = where(environment: ::Rails.env)
sc = sc.where.not(provider: user.user_authentications.pluck(:provider)) if user && !user.user_authentications.empty?
sc
}

def get_omniauth_hash(token)
strategy(token).auth_hash
end

def provider_must_be_backed_by_omniauth_strategy
errors.add(:provider, 'must be backed by an omniauth strategy') unless strategy_class.safe_constantize

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Metrics/LineLength: Line is too long. [106/80]

end

private

def strategy_class
"::OmniAuth::Strategies::#{provider.classify}".safe_constantize
end

def client
::OAuth2::Client.new(api_key, api_secret, strategy_class.default_options.client_options.to_h).tap do |c|

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Metrics/LineLength: Line is too long. [108/80]

c.site = strategy_class.default_options.client_options['site']
end
end

def access_token(token)
::OAuth2::AccessToken.new(client, token)
end

def strategy(token)
app = lambda {|env| [200, {}, ["Hello World."]]}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style/Lambda: Use the -> { ... } lambda literal syntax for single line lambdas.
Layout/SpaceInsideBlockBraces: Space between { and | missing.
Lint/UnusedBlockArgument: Unused block argument - env. If it's necessary, use _ or _env as an argument name to indicate that it won't be used. Also consider using a proc without arguments instead of a lambda if you want it to accept any arguments but don't care about them.
Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
Layout/SpaceInsideBlockBraces: Space missing inside }.

options = [api_key, api_secret]
strategy_class.new(app, *options).tap {|s| s.access_token = access_token(token)}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Layout/SpaceInsideBlockBraces: Space between { and | missing.
Metrics/LineLength: Line is too long. [84/80]
Layout/SpaceInsideBlockBraces: Space missing inside }.

end
end
9 changes: 9 additions & 0 deletions app/models/spree/user_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,13 @@ def apply_omniauth(omniauth)
def password_required?
(user_authentications.empty? || !password.blank?) && super
end

def oauth_providers
user_authentications.map do |user_authentication|
{
provider: user_authentication.provider,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Layout/IndentHash: Use 2 spaces for indentation in a hash, relative to the start of the line where the left curly brace is.

uid: user_authentication.uid
}
end
end
end
12 changes: 12 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,16 @@
namespace :admin do
resources :authentication_methods
end

namespace :api do
namespace :v1 do
resources :users do
collection do
post :social_login
post 'social_login/:provider', to: :social_login
get :oauth_providers
end
end
end
end
end
2 changes: 2 additions & 0 deletions lib/spree_social/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ def self.activate
Dir.glob(File.join(File.dirname(__FILE__), '../../app/**/*_decorator*.rb')) do |c|
Rails.configuration.cache_classes ? require(c) : load(c)
end

Spree::Api::ApiHelpers.user_attributes.push :oauth_providers
end

config.to_prepare(&method(:activate).to_proc)
Expand Down
1 change: 1 addition & 0 deletions spree_social.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,5 @@ Gem::Specification.new do |s|
s.add_development_dependency 'guard-rspec'
s.add_development_dependency 'rubocop', '>= 0.24.1'
s.add_development_dependency 'ruby_dep', '~> 1.3.0'
s.add_development_dependency 'rake', '< 11.0'
end