Skip to content
This repository has been archived by the owner on May 14, 2021. It is now read-only.

Feature/integrate new usercenter #6

Merged
merged 4 commits into from
Jun 27, 2014
Merged
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
135 changes: 35 additions & 100 deletions lib/gini-api/oauth.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,33 +25,27 @@ def initialize(api, opts)
api.client_id,
api.client_secret,
site: api.oauth_site,
authorize_url: '/authorize',
token_url: '/token',
token_url: '/oauth/token',
max_redirects: 0,
raise_errors: true,
)

# Verify opts. Prefered authorization methis is auth_code. If no auth_code is present a login from username/password
# is done.
auth_code =
# Verify opts. Prefered authorization methis is auth_code. If no auth_code is present a login from
# "Resource Owner Password Credentials Grant" flow.
# @token is a Oauth2::AccessToken object. Accesstoken is @token.token
@token =
if opts.key?(:auth_code) && !opts[:auth_code].empty?
opts[:auth_code]
# Exchange code for a token
exchange_code_for_token(api, client, opts[:auth_code])
else
# Generate CSRF token to verify the response
csrf_token = SecureRandom.hex
location = login_with_credentials(
api,
client,
csrf_token,
opts[:username],
opts[:password])
extract_auth_code(location, csrf_token)
#
login_with_resource_owner_password_credentials(
client,
opts[:username],
opts[:password],
)
end

# Exchange code for a real token.
# @token is a Oauth2::AccessToken object. Accesstoken is @token.token
@token = exchange_code_for_token(api, client, auth_code)

# Override OAuth2::AccessToken#refresh! to update self instead of returnign a new object
# Inspired by https://github.com/intridea/oauth2/issues/116#issuecomment-8097675
#
Expand Down Expand Up @@ -82,20 +76,22 @@ def @token.request(verb, path, opts = {}, &block)
# Destroy token
#
def destroy
@token.refresh_token && @token.refresh!
response = token.delete("/accessToken/#{@token.token}")
unless response.status == 204
fail_with_oauth_error(
"Failed to destroy token /accessToken/#{@token.token} "\
"(code=#{response.status})",
response
)
end
rescue OAuth2::Error => e
fail_with_oauth_error(
"Failed to destroy token (code=#{e.response.status})",
e.response
)
return "Not implemented yet. Come back later!"

# @token.refresh_token && @token.refresh!
# response = token.delete("/accessToken/#{@token.token}")
# unless response.status == 204
# fail_with_oauth_error(
# "Failed to destroy token /accessToken/#{@token.token} "\
# "(code=#{response.status})",
# response
# )
# end
# rescue OAuth2::Error => e
# fail_with_oauth_error(
# "Failed to destroy token (code=#{e.response.status})",
# e.response
# )
end

private
Expand All @@ -112,85 +108,24 @@ def fail_with_oauth_error(msg, response = nil)
)
end

# Extract auth_code from URI
# Login with resource owner password credentials
#
# @param [String] location Location URI containing the auth_code
# @param [String] csrf_token CSRF token to verify request
#
# @return [String] Collected authorization code
#
def extract_auth_code(location, csrf_token)
query_params = parse_location(location)

unless query_params['state'] == csrf_token
fail_with_oauth_error(
"CSRF token mismatch detected (should=#{csrf_token}, "\
"is=#{query_params['state']})"
)
end

unless query_params.key?('code') && !query_params['code'].empty?
fail_with_oauth_error(
"Failed to extract code from location #{location}"
)
end

query_params['code']
end

# Parse auth_code and state from URI
#
# @param [String] location Location URI with auth_code and state
#
# @return [Hash] Hash with auth_code and state
#
def parse_location(location)
# Parse the location header from the response and return hash
# {'code' => '123abc', 'state' => 'supersecret'}
q = URI.parse(location).query
Hash[*q.split(/\=|\&/)]
rescue => e
fail_with_oauth_error("Failed to parse location header: #{e.message}")
end

# Login with username/password
#
# @param [Gini::Api::Client] api API object
# @param [OAuth2::Client] client OAuth2 client object
# @param [String] csrf_token CSRF token to verify request
# @param [String] username API username
# @param [String] password API password
#
# @return [String] Location header
# @return [OAuth2::AccessToken] AccessToken object
#
def login_with_credentials(api, client, csrf_token, username, password)
# Build authentication URI
auth_uri = client.auth_code.authorize_url(
redirect_uri: api.oauth_redirect,
state: csrf_token
)

# Accquire auth code
response = client.request(
:post,
auth_uri,
body: { username: username, password: password }
)
unless response.status == 303
fail_with_oauth_error(
"API login failed (code=#{response.status})",
response
)
end
response.headers['location']
def login_with_resource_owner_password_credentials(client, username, password)
client.password.get_token(username, password)
rescue OAuth2::Error => e
fail_with_oauth_error(
"Failed to acquire auth_code (code=#{e.response.status})",
"Failed to acquire token with resource owner credentials (code=#{e.response.body})",
e.response
)
end

# Exchange auth_code for a real token
# Exchange auth_code for a access token
#
# @param [Gini::Api::Client] api API object
# @param [OAuth2::Client] client OAuth2 client object
Expand Down
3 changes: 2 additions & 1 deletion lib/gini-api/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module Gini
module Api
VERSION = "0.9.5"
# Package version
VERSION = "0.9.6"
end
end
12 changes: 6 additions & 6 deletions spec/gini-api/client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@
allow(Gini::Api::Document).to \
receive(:new).with(api, 'LOC'
) { doc }
api.token.stub(:token).and_return('abc-123')
allow(api.token).to receive(:token).and_return('abc-123')
stub_request(
:post,
%r{/documents}
Expand Down Expand Up @@ -320,7 +320,7 @@
let(:status) { 203 }

it do
api.token.stub(:delete).and_return(response)
allow(api.token).to receive(:delete).and_return(response)
expect { api.delete('abc-123') }.to \
raise_error(Gini::Api::DocumentError, /Deletion of docId abc-123 failed/)
end
Expand All @@ -332,8 +332,8 @@
let(:status) { 204 }

it do
api.token.stub(:delete).and_return(response)
expect(api.delete('abc-123')).to be_true
allow(api.token).to receive(:delete).and_return(response)
expect(api.delete('abc-123').class).to be_truthy
end

end
Expand Down Expand Up @@ -366,7 +366,7 @@
end

before do
api.token.stub(:get).and_return(OAuth2::Response.new(response))
allow(api.token).to receive(:get).and_return(OAuth2::Response.new(response))
end

context 'with documents' do
Expand Down Expand Up @@ -428,7 +428,7 @@
describe '#search' do

before do
api.token.stub(:get).and_return(OAuth2::Response.new(response))
allow(api.token).to receive(:get).and_return(OAuth2::Response.new(response))
end

let(:status) { 200 }
Expand Down
2 changes: 1 addition & 1 deletion spec/gini-api/document/extraction_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
receive(:new) { oauth }

api.login(auth_code: '1234567890')
api.token.stub(:get).with(
allow(api.token).to receive(:get).with(
location,
{
headers: {
Expand Down
28 changes: 14 additions & 14 deletions spec/gini-api/document_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
double('Gini::Api::OAuth', token: 'TOKEN', destroy: nil)
end
api.login(auth_code: '1234567890')
api.token.stub(:get).with(
allow(api.token).to receive(:get).with(
location,
{ headers: { accept: header } }
).and_return(OAuth2::Response.new(response))
Expand Down Expand Up @@ -116,7 +116,7 @@
end

it do
expect(document.completed?).to be_false
expect(document.completed?).to be_falsey
end

end
Expand All @@ -134,7 +134,7 @@
end

it do
expect(document.completed?).to be_true
expect(document.completed?).to be_truthy
end

end
Expand All @@ -156,7 +156,7 @@
end

it do
expect(document.successful?).to be_true
expect(document.successful?).to be_truthy
end

end
Expand All @@ -174,7 +174,7 @@
end

it do
expect(document.successful?).to be_false
expect(document.successful?).to be_falsey
end

end
Expand All @@ -192,7 +192,7 @@
end

it do
api.token.stub(:get).with(
allow(api.token).to receive(:get).with(
"#{location}/processed",
{ headers: { accept: 'application/octet-stream' } }
).and_return(OAuth2::Response.new(pd_response))
Expand All @@ -211,7 +211,7 @@
end

it do
api.token.stub(:get).with(
allow(api.token).to receive(:get).with(
"#{location}/processed",
{ headers: { accept: 'application/octet-stream' } }
).and_return(OAuth2::Response.new(pd_response))
Expand All @@ -236,7 +236,7 @@
end

it do
api.token.stub(:get).with(
allow(api.token).to receive(:get).with(
"#{location}/extractions",
{ headers: { accept: header } }
).and_return(OAuth2::Response.new(ex_response))
Expand Down Expand Up @@ -312,8 +312,8 @@
let(:fb_response) { double('Response', status: 204) }

it do
document.stub(:extractions) { double('Extractions').as_null_object }
api.token.stub(:put).with(
allow(document).to receive(:extractions) { double('Extractions').as_null_object }
allow(api.token).to receive(:put).with(
"#{location}/extractions/bic",
{
headers: { 'content-type' => header },
Expand All @@ -331,8 +331,8 @@
let(:fb_response) { double('Response', status: 204) }

it 'on invalid label' do
document.stub(:extractions) { double('Extractions', bic: nil) }
api.token.stub(:put).with(
allow(document).to receive(:extractions) { double('Extractions', bic: nil) }
allow(api.token).to receive(:put).with(
"#{location}/extractions/bic",
{
headers: { 'content-type' => header },
Expand All @@ -351,8 +351,8 @@
let(:fb_response) { double('Response', status: 404, body: {}, env: {}) }

it 'on invalid http code' do
document.stub(:extractions) { double('Extractions').as_null_object }
api.token.stub(:put).with(
allow(document).to receive(:extractions) { double('Extractions').as_null_object }
allow(api.token).to receive(:put).with(
"#{location}/extractions/bic",
{
headers: { 'content-type' => header },
Expand Down
2 changes: 1 addition & 1 deletion spec/gini-api/error_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
end

before do
api.token.stub(:get).and_return(response)
allow(api.token).to receive(:get).and_return(response)
end

context 'without request obj' do
Expand Down
Loading