Skip to content

Instantly share code, notes, and snippets.

@kedarmhaswade
Created May 3, 2012 02:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kedarmhaswade/2582579 to your computer and use it in GitHub Desktop.
Save kedarmhaswade/2582579 to your computer and use it in GitHub Desktop.
# Demo::Rack::ApiAccess is a rack middleware and implements the rack interface.
# Its purpose is to validate the API access. In essence, it "logs in" the user for which
# the current request has an access_token.
require 'oauth2/provider/models/active_record/access_token'
module Demo::Rack
class ApiAccess
def initialize(app)
@app = app
end
def call(env)
request = Rack::Request.new(env)
t = request.params['access_token'] || request.params['oauth_token']
if t # appears an API request
begin
status, headers, body = validate t, request
if (status == 200) # that means this token is valid and user is in the session, pass on the control, don't return to the user!
@app.call env
else
[status, headers, body] # terminate the request by sending the response (TODO too much of array/scalar conversion here)
end
rescue => e
[500, headers, {"error" => "Contact Support, unexpected error: #{e.message}"}]
end
else # appears a non-API request, don't do anything
@app.call env
end
end
private
# Establishes if the token is valid and saves the associated resource_owner as the current_user_id in session.
def validate(t, request)
require 'json'
status = 200
headers = {}
body = {}
unless valid_api_request? request
status = 400
body["error"] = "Only XML or JSON requests are allowed."
return [status, headers, body.to_json]
end
begin
at = OAuth2::Provider::Models::ActiveRecord::AccessToken.find_by_access_token(t)
if not at
body["error"] = "Access-token #{t} is not valid."
status = 400
elsif not at.authorization
body["error"] = "The access-token #{t} exists, but there is no associated authorization. Please contact support with this message."
status = 400
elsif at.expired?
body["error"] = "This access-token is now expired. Please refresh it with refresh-token procedure"
status = 400
else # everything is hunky dory, log the user in, hopefully, the authorization is valid
owner = at.authorization.resource_owner
if owner.is_a? User
request.session[:current_user_id] = owner.id # finally! # <= works only for GET requests, is that possible?
status = 200 # just in case ... :-)
end
end
rescue => e
status = 400
headers["Content-Type"] = "text/plain"
body["error"] = "Unexpected API Access Failure"
body["error_description"] = e.message
body["stack_trace"] = e.backtrace.join("\n")
end
[status, headers, body.to_json]
end
def valid_api_request?(request)
# API request can only be xml or json.
# TODO: Add more rules..
request.path.ends_with?(".xml") || request.path.ends_with?(".json")
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment