Created
May 3, 2012 02:17
-
-
Save kedarmhaswade/2582579 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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