Today it only supports a single provider. --- lib/aeolus_image.rb | 1 + lib/aeolus_image/active_resource_oauth_client.rb | 54 ++++++++++++++++++++++ lib/aeolus_image/model/factory/base.rb | 16 ++++++- 3 files changed, 70 insertions(+), 1 deletions(-) create mode 100644 lib/aeolus_image/active_resource_oauth_client.rb
diff --git a/lib/aeolus_image.rb b/lib/aeolus_image.rb index 15e88d8..aeb6bcc 100644 --- a/lib/aeolus_image.rb +++ b/lib/aeolus_image.rb @@ -29,3 +29,4 @@ require File.join(File.dirname(__FILE__), 'aeolus_image/model/factory', 'build') require File.join(File.dirname(__FILE__), 'aeolus_image/model/factory', 'provider_image') require File.join(File.dirname(__FILE__), 'aeolus_image/model/factory', 'target_image') require File.join(File.dirname(__FILE__), 'aeolus_image/model/factory', 'builder') +require File.join(File.dirname(__FILE__), 'aeolus_image', 'oauth_client') diff --git a/lib/aeolus_image/active_resource_oauth_client.rb b/lib/aeolus_image/active_resource_oauth_client.rb new file mode 100644 index 0000000..f44ef1f --- /dev/null +++ b/lib/aeolus_image/active_resource_oauth_client.rb @@ -0,0 +1,54 @@ +# Copyright 2011 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'oauth' + +# Monkey-patch ActiveResource to allow us to merge our OAuth headers in. +module ActiveResourceOAuthClient + ActiveResource::Connection.class_eval do + def request_with_oauth(method, path, *arguments) + @oauth_config = Aeolus::Image::Factory::Base.config || {} + # Take care to fall back to the standard request method if we don't have full OAuth credentials + request_without_oauth(method, path, *arguments) unless Aeolus::Image::Factory::Base.use_oauth? + result = ActiveSupport::Notifications.instrument("request.active_resource") do |payload| + payload[:method] = method + payload[:request_uri] = "#{site.scheme}://#{site.host}:#{site.port}#{path}" + oauth_consumer = OAuth::Consumer.new( + @oauth_config[:consumer_key], + @oauth_config[:consumer_secret], + :site => @oauth_config[:site] ) + 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 + + alias_method_chain :request, :oauth + + end +end diff --git a/lib/aeolus_image/model/factory/base.rb b/lib/aeolus_image/model/factory/base.rb index aaab90a..7947da1 100644 --- a/lib/aeolus_image/model/factory/base.rb +++ b/lib/aeolus_image/model/factory/base.rb @@ -38,6 +38,20 @@ module Aeolus self.class.new.load(object_array) end end + + # This approach does mean you're limited to one server at a time + def config + defined?(@@config) ? @@config : {} + end + def config=(conf={}) + @@config = conf + self.site = @@config[:site] + end + + # Should we use OAuth? + def use_oauth? + config[:consumer_key] && config[:consumer_secret] && config[:site] + end end
## Instance Methods: (modifying the ActiveRecord::CustomMethods). @@ -61,4 +75,4 @@ module Aeolus end end end -end \ No newline at end of file +end