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

Commit

Permalink
Merge pull request #6 from gini/feature/integrate_new_usercenter
Browse files Browse the repository at this point in the history
Feature/integrate new usercenter
  • Loading branch information
dkerwin committed Jun 27, 2014
2 parents d5c0206 + 3338c51 commit 227f075
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 228 deletions.
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

0 comments on commit 227f075

Please sign in to comment.