Update, works now
This commit is contained in:
parent
3e436024cf
commit
609e552cb9
6 changed files with 182 additions and 108 deletions
|
@ -1,2 +1,3 @@
|
|||
require "omniauth-mapsme/version"
|
||||
require "omniauth/strategies/mapsme"
|
||||
require "omniauth/strategies/mapsme-token"
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
module Omniauth
|
||||
module Mapsme
|
||||
VERSION = "0.1.1"
|
||||
module OmniAuth
|
||||
module MapsMe
|
||||
VERSION = "1.0.0"
|
||||
end
|
||||
|
||||
module MapsMeToken
|
||||
VERSION = MapsMe::VERSION
|
||||
end
|
||||
end
|
||||
|
|
13
lib/omniauth/strategies/mapsme-base.rb
Normal file
13
lib/omniauth/strategies/mapsme-base.rb
Normal file
|
@ -0,0 +1,13 @@
|
|||
module OmniAuth
|
||||
module Strategies
|
||||
module MapsMeBase
|
||||
MAPSME_BASE = 'http://yershov.passport.map6.devmail.ru'
|
||||
|
||||
MAPSME_CLIENT_OPTIONS = {
|
||||
:site => MAPSME_BASE,
|
||||
:authorize_url => "#{MAPSME_BASE}/oauth/authorize",
|
||||
:token_url => "#{MAPSME_BASE}/oauth/token"
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
127
lib/omniauth/strategies/mapsme-token.rb
Normal file
127
lib/omniauth/strategies/mapsme-token.rb
Normal file
|
@ -0,0 +1,127 @@
|
|||
require 'oauth2'
|
||||
require 'omniauth'
|
||||
require_relative 'mapsme-base'
|
||||
|
||||
module OmniAuth
|
||||
module Strategies
|
||||
class MapsMeToken
|
||||
include OmniAuth::Strategy
|
||||
include OmniAuth::Strategies::MapsMeBase
|
||||
|
||||
option :name, 'mapsme_token'
|
||||
|
||||
args [:client_id, :client_secret]
|
||||
|
||||
option :client_id, nil
|
||||
option :client_secret, nil
|
||||
|
||||
option :client_options, MAPSME_CLIENT_OPTIONS
|
||||
|
||||
option :access_token_options, {
|
||||
:header_format => 'OAuth %s',
|
||||
:param_name => 'access_token'
|
||||
}
|
||||
|
||||
attr_accessor :access_token
|
||||
|
||||
uid { raw_info['uid'].to_s }
|
||||
|
||||
info do
|
||||
prune!({
|
||||
'email' => raw_info['email'],
|
||||
'name' => raw_info['name']
|
||||
})
|
||||
end
|
||||
|
||||
extra do
|
||||
{ :raw_info => raw_info }
|
||||
end
|
||||
|
||||
credentials do
|
||||
hash = {'token' => access_token.token}
|
||||
hash.merge!('refresh_token' => access_token.refresh_token) if access_token.expires? && access_token.refresh_token
|
||||
hash.merge!('expires_at' => access_token.expires_at) if access_token.expires?
|
||||
hash.merge!('expires' => access_token.expires?)
|
||||
hash
|
||||
end
|
||||
|
||||
def authorize_params
|
||||
super.tap do |params|
|
||||
params[:scope] = 'user mail'
|
||||
end
|
||||
end
|
||||
|
||||
def raw_info
|
||||
@raw_info ||= access_token.get('/user').parsed || {}
|
||||
end
|
||||
|
||||
def info_options
|
||||
options[:info_fields] ? {:params => {:fields => options[:info_fields]}} : {}
|
||||
end
|
||||
|
||||
def client
|
||||
::OAuth2::Client.new(options.client_id, options.client_secret, deep_symbolize(options.client_options))
|
||||
end
|
||||
|
||||
def request_phase
|
||||
form = OmniAuth::Form.new(:title => "User Token", :url => callback_path)
|
||||
form.text_field "Access Token", "access_token"
|
||||
form.button "Sign In"
|
||||
form.to_response
|
||||
end
|
||||
|
||||
def callback_phase
|
||||
if !request.params['access_token'] || request.params['access_token'].to_s.empty?
|
||||
raise ArgumentError.new("No access token provided.")
|
||||
end
|
||||
|
||||
self.access_token = build_access_token
|
||||
self.access_token = self.access_token.refresh! if self.access_token.expired?
|
||||
|
||||
# Instead of calling super, duplicate the functionality, but change the provider to 'mapsme'.
|
||||
# So the list of accounts is single for both strategies.
|
||||
hash = auth_hash
|
||||
hash[:provider] = "mapsme"
|
||||
self.env['omniauth.auth'] = hash
|
||||
call_app!
|
||||
|
||||
rescue ::OAuth2::Error => e
|
||||
fail!(:invalid_credentials, e)
|
||||
rescue ::MultiJson::DecodeError => e
|
||||
fail!(:invalid_response, e)
|
||||
rescue ::Timeout::Error, ::Errno::ETIMEDOUT => e
|
||||
fail!(:timeout, e)
|
||||
rescue ::SocketError => e
|
||||
fail!(:failed_to_connect, e)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def deep_symbolize(hash)
|
||||
hash.inject({}) do |h, (k,v)|
|
||||
h[k.to_sym] = v.is_a?(Hash) ? deep_symbolize(v) : v
|
||||
h
|
||||
end
|
||||
end
|
||||
|
||||
def build_access_token
|
||||
# Options supported by `::OAuth2::AccessToken#initialize` and not overridden by `access_token_options`
|
||||
hash = request.params.slice("access_token", "expires_at", "expires_in", "refresh_token")
|
||||
hash.update(options.access_token_options)
|
||||
::OAuth2::AccessToken.from_hash(
|
||||
client,
|
||||
hash
|
||||
)
|
||||
end
|
||||
|
||||
def prune!(hash)
|
||||
hash.delete_if do |_, value|
|
||||
prune!(value) if value.is_a?(Hash)
|
||||
value.nil? || (value.respond_to?(:empty?) && value.empty?)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
OmniAuth.config.add_camelization 'mapsme', 'MapsMe'
|
|
@ -1,129 +1,56 @@
|
|||
require 'oauth2'
|
||||
require 'omniauth'
|
||||
require 'omniauth-oauth2'
|
||||
require_relative 'mapsme-base'
|
||||
|
||||
module OmniAuth
|
||||
module Strategies
|
||||
class MapsMeToken
|
||||
include OmniAuth::Strategy
|
||||
class MapsMe < OmniAuth::Strategies::OAuth2
|
||||
include OmniAuth::Strategies::MapsMeBase
|
||||
|
||||
option :name, 'mapsme_token'
|
||||
option :name, 'mapsme'
|
||||
|
||||
args [:client_id, :client_secret]
|
||||
option :client_options, MAPSME_CLIENT_OPTIONS
|
||||
|
||||
option :client_id, nil
|
||||
option :client_secret, nil
|
||||
|
||||
option :client_options, {
|
||||
:site => 'https://passport.maps.me',
|
||||
:authorize_url => 'https://passport.maps.me/oauth/authorize',
|
||||
:token_url => 'https://passport.maps.me/oauth/access_token'
|
||||
}
|
||||
|
||||
option :access_token_options, {
|
||||
:header_format => 'OAuth %s',
|
||||
:param_name => 'access_token'
|
||||
}
|
||||
|
||||
attr_accessor :access_token
|
||||
|
||||
uid { raw_info['id'] }
|
||||
uid { raw_info['uid'].to_s }
|
||||
|
||||
info do
|
||||
prune!({
|
||||
{
|
||||
'email' => raw_info['email'],
|
||||
'name' => raw_info['name']
|
||||
})
|
||||
}
|
||||
end
|
||||
|
||||
extra do
|
||||
hash = {}
|
||||
hash['raw_info'] = raw_info unless skip_info?
|
||||
prune! hash
|
||||
{ :raw_info => raw_info }
|
||||
end
|
||||
|
||||
credentials do
|
||||
hash = {'token' => access_token.token}
|
||||
hash.merge!('refresh_token' => access_token.refresh_token) if access_token.expires? && access_token.refresh_token
|
||||
hash.merge!('expires_at' => access_token.expires_at) if access_token.expires?
|
||||
hash.merge!('expires' => access_token.expires?)
|
||||
hash
|
||||
def authorize_params
|
||||
super.tap do |params|
|
||||
params[:scope] = 'user mail'
|
||||
end
|
||||
end
|
||||
|
||||
def raw_info
|
||||
@raw_info ||= access_token.get('/user', info_options).parsed || {}
|
||||
@raw_info ||= access_token.get('/user').parsed || {}
|
||||
end
|
||||
|
||||
def info_options
|
||||
options[:info_fields] ? {:params => {:fields => options[:info_fields]}} : {}
|
||||
end
|
||||
|
||||
def client
|
||||
::OAuth2::Client.new(options.client_id, options.client_secret, deep_symbolize(options.client_options))
|
||||
end
|
||||
|
||||
def request_phase
|
||||
form = OmniAuth::Form.new(:title => "User Token", :url => callback_path)
|
||||
form.text_field "Access Token", "access_token"
|
||||
form.button "Sign In"
|
||||
form.to_response
|
||||
end
|
||||
|
||||
def callback_phase
|
||||
if !request.params['access_token'] || request.params['access_token'].to_s.empty?
|
||||
raise ArgumentError.new("No access token provided.")
|
||||
end
|
||||
|
||||
self.access_token = build_access_token
|
||||
self.access_token = self.access_token.refresh! if self.access_token.expired?
|
||||
|
||||
# Validate that the token belong to the application
|
||||
app_raw = self.access_token.get('/app').parsed
|
||||
if app_raw["id"] != options.client_id.to_s
|
||||
raise ArgumentError.new("Access token doesn't belong to the client.")
|
||||
end
|
||||
|
||||
# Instead of calling super, duplicate the functionlity, but change the provider to 'mapsme'.
|
||||
# In case we someday publish a mapsme auth provider.
|
||||
hash = auth_hash
|
||||
hash[:provider] = "mapsme"
|
||||
self.env['omniauth.auth'] = hash
|
||||
call_app!
|
||||
|
||||
rescue ::OAuth2::Error => e
|
||||
fail!(:invalid_credentials, e)
|
||||
rescue ::MultiJson::DecodeError => e
|
||||
fail!(:invalid_response, e)
|
||||
rescue ::Timeout::Error, ::Errno::ETIMEDOUT => e
|
||||
fail!(:timeout, e)
|
||||
rescue ::SocketError => e
|
||||
fail!(:failed_to_connect, e)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def deep_symbolize(hash)
|
||||
hash.inject({}) do |h, (k,v)|
|
||||
h[k.to_sym] = v.is_a?(Hash) ? deep_symbolize(v) : v
|
||||
h
|
||||
end
|
||||
end
|
||||
# Fix omniauth-oauth2 issue https://github.com/intridea/omniauth-oauth2/issues/76
|
||||
|
||||
def build_access_token
|
||||
# Options supported by `::OAuth2::AccessToken#initialize` and not overridden by `access_token_options`
|
||||
hash = request.params.slice("access_token", "expires_at", "expires_in", "refresh_token")
|
||||
hash.update(options.access_token_options)
|
||||
::OAuth2::AccessToken.from_hash(
|
||||
client,
|
||||
hash
|
||||
)
|
||||
options.token_params.merge!(:headers => {'Authorization' => basic_auth_header })
|
||||
super
|
||||
end
|
||||
|
||||
def prune!(hash)
|
||||
hash.delete_if do |_, value|
|
||||
prune!(value) if value.is_a?(Hash)
|
||||
value.nil? || (value.respond_to?(:empty?) && value.empty?)
|
||||
end
|
||||
def basic_auth_header
|
||||
"Basic " + Base64.strict_encode64("#{options[:client_id]}:#{options[:client_secret]}")
|
||||
end
|
||||
|
||||
# Fix omniauth-oauth2 issue https://github.com/intridea/omniauth-oauth2/issues/93
|
||||
|
||||
def callback_url
|
||||
full_host + script_name + callback_path
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
OmniAuth.config.add_camelization 'mapsme', 'MapsMe'
|
||||
|
|
|
@ -5,17 +5,19 @@ require 'omniauth-mapsme/version'
|
|||
|
||||
Gem::Specification.new do |spec|
|
||||
spec.name = "omniauth-mapsme"
|
||||
spec.version = Omniauth::Mapsme::VERSION
|
||||
spec.version = OmniAuth::MapsMe::VERSION
|
||||
spec.authors = ["Ilya Zverev"]
|
||||
spec.email = ["ilya@zverev.info"]
|
||||
|
||||
spec.summary = %q{MAPS.ME passport strategy for OmniAuth}
|
||||
spec.description = %q{MAPS.ME passport strategy for OmniAuth. Uses provided access token.}
|
||||
spec.homepage = "http://maps.me"
|
||||
spec.description = %q{MAPS.ME passport strategy for OmniAuth, complete with regual and access token strategies}
|
||||
spec.homepage = "http://maps.me/"
|
||||
spec.license = "MIT"
|
||||
|
||||
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
||||
spec.require_paths = ["lib"]
|
||||
|
||||
spec.add_dependency "omniauth-oauth2", ">= 1.1.1"
|
||||
spec.add_dependency "omniauth", "~> 1.2"
|
||||
spec.add_dependency "oauth2", "~> 1.0"
|
||||
spec.add_dependency "omniauth-oauth2", "~> 1.4"
|
||||
end
|
||||
|
|
Loading…
Add table
Reference in a new issue