Commit 44da9387 authored by Vinoth Kannan's avatar Vinoth Kannan

REFACTOR: Use base class methods and 'Oauth2UserInfo' instead of 'PluginStore'

parent 41a5d0a3
......@@ -10,40 +10,25 @@ enabled_site_setting :oauth2_enabled
class ::OmniAuth::Strategies::Oauth2Basic < ::OmniAuth::Strategies::OAuth2
option :name, "oauth2_basic"
uid {
raw_info[:user_id]
}
info do
{
id: access_token['id']
username: raw_info[:username],
email: raw_info[:email],
name: raw_info[:name],
access_token: access_token.token,
refresh_token: access_token.refresh_token
}
end
def callback_url
full_host + script_name + callback_path
end
end
class OAuth2BasicAuthenticator < ::Auth::OAuth2Authenticator
def register_middleware(omniauth)
omniauth.provider :oauth2_basic,
name: 'oauth2_basic',
setup: lambda { |env|
opts = env['omniauth.strategy'].options
opts[:client_id] = SiteSetting.oauth2_client_id
opts[:client_secret] = SiteSetting.oauth2_client_secret
opts[:provider_ignores_state] = false
opts[:client_options] = {
authorize_url: SiteSetting.oauth2_authorize_url,
token_url: SiteSetting.oauth2_token_url
}
opts[:authorize_options] = SiteSetting.oauth2_authorize_options.split("|").map(&:to_sym)
if SiteSetting.oauth2_send_auth_header?
opts[:token_params] = { headers: { 'Authorization' => basic_auth_header } }
end
}
end
def basic_auth_header
"Basic " + Base64.strict_encode64("#{SiteSetting.oauth2_client_id}:#{SiteSetting.oauth2_client_secret}")
extra do
{
raw_info: raw_info
}
end
def walk_path(fragment, segments)
......@@ -64,59 +49,71 @@ class OAuth2BasicAuthenticator < ::Auth::OAuth2Authenticator
end
end
def log(info)
Rails.logger.warn("OAuth2 Debugging: #{info}") if SiteSetting.oauth2_debug_auth
end
def raw_info
@raw_info ||= begin
token = credentials["token"].to_s
id = access_token["id"].to_s
user_json_url = SiteSetting.oauth2_user_json_url.sub(':token', token).sub(':id', id)
def fetch_user_details(token, id)
user_json_url = SiteSetting.oauth2_user_json_url.sub(':token', token.to_s).sub(':id', id.to_s)
OAuth2BasicAuthenticator.log("user_json_url: #{user_json_url}")
log("user_json_url: #{user_json_url}")
user_json = JSON.parse(open(user_json_url, 'Authorization' => "Bearer #{token}").read)
user_json = JSON.parse(open(user_json_url, 'Authorization' => "Bearer #{token}").read)
OAuth2BasicAuthenticator.log("user_json: #{user_json}")
log("user_json: #{user_json}")
result = {}
if user_json.present?
json_walk(result, user_json, :user_id)
json_walk(result, user_json, :username)
json_walk(result, user_json, :name)
json_walk(result, user_json, :email)
end
result = {}
if user_json.present?
json_walk(result, user_json, :user_id)
json_walk(result, user_json, :username)
json_walk(result, user_json, :name)
json_walk(result, user_json, :email)
result
end
end
result
def callback_url
full_host + script_name + callback_path
end
end
def after_authenticate(auth)
log("after_authenticate response: \n\ncreds: #{auth['credentials'].to_hash}\ninfo: #{auth['info'].to_hash}\nextra: #{auth['extra'].to_hash}")
result = Auth::Result.new
token = auth['credentials']['token']
user_details = fetch_user_details(token, auth['info'][:id])
result.name = user_details[:name]
result.username = user_details[:username]
result.email = user_details[:email]
result.email_valid = result.email.present? && SiteSetting.oauth2_email_verified?
current_info = ::PluginStore.get("oauth2_basic", "oauth2_basic_user_#{user_details[:user_id]}")
if current_info
result.user = User.where(id: current_info[:user_id]).first
elsif SiteSetting.oauth2_email_verified?
result.user = User.find_by_email(result.email)
if result.user && user_details[:user_id]
::PluginStore.set("oauth2_basic", "oauth2_basic_user_#{user_details[:user_id]}", user_id: result.user.id)
end
end
class OAuth2BasicAuthenticator < ::Auth::OAuth2Authenticator
result.extra_data = { oauth2_basic_user_id: user_details[:user_id] }
result
def self.log(info)
Rails.logger.warn("OAuth2 Debugging: #{info}") if SiteSetting.oauth2_debug_auth
end
def after_create_account(user, auth)
::PluginStore.set("oauth2_basic", "oauth2_basic_user_#{auth[:extra_data][:oauth2_basic_user_id]}", user_id: user.id)
def register_middleware(omniauth)
omniauth.provider :oauth2_basic,
name: 'oauth2_basic',
setup: lambda { |env|
opts = env['omniauth.strategy'].options
opts[:client_id] = SiteSetting.oauth2_client_id
opts[:client_secret] = SiteSetting.oauth2_client_secret
opts[:provider_ignores_state] = false
opts[:client_options] = {
authorize_url: SiteSetting.oauth2_authorize_url,
token_url: SiteSetting.oauth2_token_url
}
opts[:authorize_options] = SiteSetting.oauth2_authorize_options.split("|").map(&:to_sym)
if SiteSetting.oauth2_send_auth_header?
opts[:token_params] = { headers: { 'Authorization' => basic_auth_header } }
end
}
end
def basic_auth_header
"Basic " + Base64.strict_encode64("#{SiteSetting.oauth2_client_id}:#{SiteSetting.oauth2_client_secret}")
end
def after_authenticate(auth)
OAuth2BasicAuthenticator.log("after_authenticate response: \n\ncreds: #{auth[:credentials]}\ninfo: #{auth[:info]}\nextra: #{auth[:extra]}")
@opts[:trusted] = SiteSetting.oauth2_email_verified?
super(auth)
end
end
auth_provider title_setting: "oauth2_button_title",
......
......@@ -29,13 +29,20 @@ describe OAuth2BasicAuthenticator do
it 'finds user by email' do
authenticator = OAuth2BasicAuthenticator.new('oauth2_basic')
user = Fabricate(:user)
authenticator.expects(:fetch_user_details).returns(email: user.email)
SiteSetting.oauth2_email_verified = true
auth = { 'credentials' => { 'token': 'token' },
'info' => { id: 'id' },
'extra' => {} }
auth = { credentials: { token: 'token' }, uid: 'id', provider: "oauth2_basic", info: { email: user.email }, extra: {} }
result = authenticator.after_authenticate(auth)
result = {}
expect {
result = authenticator.after_authenticate(auth)
}.to change { Oauth2UserInfo.count }.by(1)
expect(result.user).to eq(user)
expect(Oauth2UserInfo.find_by(uid: 'id', provider: "oauth2_basic").user_id).to eq(user.id)
expect {
result = authenticator.after_authenticate(auth)
}.to change { Oauth2UserInfo.count }.by(0)
expect(result.user).to eq(user)
end
......
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