Skip to content

Commit

Permalink
ImageFactory OAuth request support
Browse files Browse the repository at this point in the history
Adds in the ability to use 2 Legged OAuth for securing
requests to imagefactory.
  • Loading branch information
mtaylor committed Jan 25, 2013
1 parent bd51b70 commit 45eda16
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 1 deletion.
15 changes: 15 additions & 0 deletions README.rdoc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,21 @@ Tim wraps all this up in a clean, simply RESTful API.
You can read the full presentation
here[http://www.aeolusproject.org/docs/presentations/2012-nov-conference/tim.odp].

== Configuration

=== Securing Image Factory requests

It is possible to secure Image Factory requests using 2 Legged OAuth. To use 2
Legged OAuth you must set the OAuth consumer key, consumer secret and url in the
Tim::ImageFactory::Base.config.

Example:

oauth_config = {:consumer_key => "mock-key",
:consumer_secret => "mock-secret",
:site => "http://localhost:8075/imagefactory/"}
Tim::ImageFactory::Base.config = oauth_config

== Running Tests

{<img src="https://secure.travis-ci.org/aeolus-incubator/tim.png"
Expand Down
3 changes: 2 additions & 1 deletion lib/image_factory/image_factory.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require "active_resource"
require File.join(File.dirname(__FILE__), 'oauth', 'active_resource_oauth_client')
require File.join(File.dirname(__FILE__), 'model', 'base')
require File.join(File.dirname(__FILE__), 'model', 'target_image')
require File.join(File.dirname(__FILE__), 'model', 'provider_image')
require File.join(File.dirname(__FILE__), 'model', 'provider_image')
52 changes: 52 additions & 0 deletions lib/image_factory/oauth/active_resource_oauth_client.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
require 'oauth'

# Monkey-patch ActiveResource to allow us to merge our OAuth headers in.
# Portions of the below are taken from Active Resource which is MIT licensed;
# hence this whole file is being licensed under the MIT License to err on the side of safety.
module ActiveResourceOAuthClient
ActiveResource::Connection.class_eval do
def request_with_oauth(method, path, *arguments)
@oauth_config = Tim::ImageFactory::Base.config || {}
# Take care to fall back to the standard request method if we don't have full OAuth credentials
unless use_oauth_for_url?("#{site.scheme}://#{site.host}:#{site.port}#{path}")
return request_without_oauth(method, path, *arguments)
end
result = ActiveSupport::Notifications.instrument("request.active_resource") do |payload|
payload[:method] = method
payload[:request_uri] = "#{site.scheme}://#{site.host}:#{site.port}#{path}"
puts "#{payload[:method]} #{payload[:request_uri]}"
oauth_consumer = OAuth::Consumer.new(
@oauth_config[:consumer_key],
@oauth_config[:consumer_secret],
:site => @oauth_config[:site] )
puts @oauth_config[:consumer_key] + " " + @oauth_config[:consumer_secret]
token = OAuth::AccessToken.new(oauth_consumer)
base_request = oauth_consumer.create_signed_request(method, path, token, {}, *arguments)
payload[:result] = http.request(base_request)
end
# Error-handling code from OAuth
# http://wiki.oauth.net/w/page/12238543/ProblemReporting
auth_header = result.to_hash['www-authenticate']
problem_header = auth_header ? auth_header.select{|h| h =~ /^OAuth /}.select{|h| h =~ /oauth_problem/}.first : nil
if auth_header && problem_header
params = OAuth::Helper.parse_header(problem_header)
raise OAuth::Problem.new(params.delete("oauth_problem"), result, params)
end
# Error-handling code from ActiveResource
handle_response(result)
rescue Timeout::Error => e
raise TimeoutError.new(e.message)
rescue OpenSSL::SSL::SSLError => e
raise SSLError.new(e.message)
end

# Currently, only Factory calls should use OAuth -- extend as needed
def use_oauth_for_url?(url)
Tim::ImageFactory::Base.use_oauth? and
url.include?(Tim::ImageFactory::Base.config[:site])
end

alias_method_chain :request, :oauth

end
end
8 changes: 8 additions & 0 deletions test/dummy/config/initializers/tim.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
Tim.user_class = "User"
Tim.provider_account_class = "ProviderAccount"
Tim.provider_type_class = "ProviderType"

# Image Factory URL
Tim::ImageFactory::Base.site = "http://localhost:8075/imagefactory"

# Example OAuth Configuration
#oauth_config = {:consumer_key => "mock-key",
# :consumer_secret => "mock-secret",
# :site => "http://localhost:8075/imagefactory/"}#
#Tim::ImageFactory::Base.config = oauth_config

# FIXME: We should be able to infer these from Routes
Tim::ImageFactory::TargetImage.callback_url = "http://localhost:3000/tim/target_images/"
Tim::ImageFactory::ProviderImage.callback_url = "http://localhost:3000/tim/provider_images/"
1 change: 1 addition & 0 deletions tim.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Gem::Specification.new do |s|
s.add_dependency "rails", "~> 3.2"
s.add_dependency "haml"
s.add_dependency "nokogiri"
s.add_dependency "oauth"

s.add_development_dependency "sqlite3"
s.add_development_dependency "rspec-rails"
Expand Down

0 comments on commit 45eda16

Please sign in to comment.