diff --git a/README.md b/README.md index 2187572e..2b367f79 100644 --- a/README.md +++ b/README.md @@ -248,6 +248,30 @@ def api_authenticate end ``` +### Server signing response + +The server can perform a validation of the response. + +You can add the validation in the controller : + +```ruby + class ApplicationController < ActiveController::Base + validation_with_api_auth(access_id: 'test', secret_key: 'test', options: { digest: 'sha256' } ) + end +``` + +or specified at every render + +```ruby + class ApplicationController < ActiveController::Base + validation_with_api_auth() + + def index + render json: @users, api_auth: { access_id: 'test', secret_key: 'test', options: { digest: 'sha256' }} + end + end +``` + ## Development ApiAuth uses bundler for gem dependencies and RSpec for testing. Developing the diff --git a/lib/api_auth/headers.rb b/lib/api_auth/headers.rb index 53cddbbd..c8c1ef80 100644 --- a/lib/api_auth/headers.rb +++ b/lib/api_auth/headers.rb @@ -30,6 +30,8 @@ def initialize_request_driver(request) GrapeRequest.new(request) when /ActionDispatch::Request/ ActionDispatchRequest.new(request) + when /ActionDispatch::Response/ + ActionDispatchRequest.new(request) when /ActionController::CgiRequest/ ActionControllerRequest.new(request) when /HTTPI::Request/ diff --git a/lib/api_auth/railtie.rb b/lib/api_auth/railtie.rb index 501a2be4..03a47564 100644 --- a/lib/api_auth/railtie.rb +++ b/lib/api_auth/railtie.rb @@ -13,7 +13,40 @@ def api_authenticated?(secret_key) end end + module ClassMethods + def validation_with_api_auth(api_auth_options = nil) + ActionController.add_renderer(:json) do |json, options| + api_auth_options ||= options[:api_auth] + options.delete(:api_auth) + + json = json.to_json(options) unless json.is_a?(String) + + if options[:callback].present? + self.content_type = Mime[:js] if content_type.nil? || content_type == Mime[:json] + + "/**/#{options[:callback]}(#{json})" + else + self.content_type ||= Mime[:json] + + # API AUTH addition headers + if api_auth_options + response.headers['CONTENT-MD5'] ||= Digest::MD5.base64digest(json) + response.headers['Authorization'] ||= ApiAuth.sign!( + request, + api_auth_options[:access_id], + api_auth_options[:secret_key], + api_auth_options[:options] || {} + ).env['Authorization'] + end + + json + end + end + end + end + ActionController::Base.send(:include, ControllerMethods::InstanceMethods) if defined?(ActionController::Base) + ActionController::Base.send(:extend, ControllerMethods::ClassMethods) if defined?(ActionController::Base) end # ControllerMethods module ActiveResourceExtension # :nodoc: