Skip to content

Instantly share code, notes, and snippets.

@radixhound
Created July 1, 2011 19:47
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 radixhound/1059261 to your computer and use it in GitHub Desktop.
Save radixhound/1059261 to your computer and use it in GitHub Desktop.
class MongoAuth
include Goliath::Rack::AsyncMiddleware
include Goliath::Validation
include Goliath::Rack::Validator
class MissingApikeyError < BadRequestError ; end
class DatabaseSaveError < BadRequestError ; end
class RateLimitExceededError < ForbiddenError ; end
class UserIDMismatchError < UnauthorizedError ; end
def initialize(app, db_name)
@app = app
@db_name = db_name
end
def call(env)
@env = env
@db = env.config[@db_name]
env.trace('auth pre-process')
if requires_authentication?
if auth_key = read_authorization_header
lookup_auth_token(auth_key) #async call to db happens here
else
raise MissingApikeyError, "can't read auth key from header"
end
end
super(env)
end
private
def requires_authentication?
@env[Goliath::Request::REQUEST_METHOD] =~ /(POST|PUT)/ unless Goliath.env.to_s == "test" #returns true on POST, false otherwise
end
def is_get_request?
@env[Goliath::Request::REQUEST_METHOD] == 'GET'
end
def read_authorization_header
if @env['async-headers']['Authorization'] =~ /^FTAuth\s(.*)/
auth_key = $1
else
false
end
end
# check the database - this is where the async call happens
def lookup_auth_token(auth_key)
first('users', { :authentication_token => auth_key }) do |res|
@env.trace('auth responded')
if res
@env['user_id']= res['_id']
@env['authenticated'] = true
else
@env['user_id'] = 0
@env['authenticated'] = false
end
end
end
def db
@db
end
def find(collection, selector={}, opts={}, &block)
db.collection(collection).find(selector, opts) do |result|
yield result
end
end
def first(collection, selector={}, opts={}, &block)
opts[:limit] = 1
find(collection, selector, opts) do |result|
yield result.first
end
end
end
Tracers for thread 1
--------------------------------------------
1-0 :: do login done in 0.200142
[:object_id, "4e0e21a7df715b0930000017"][:return, "User saved successfully"]
1-2 :: change username done in 0.926572
--
[:error, "Invalid auth token / token not found"]
1-5 :: change username done in 0.020906
--
[:error, "Invalid auth token / token not found"]
1-8 :: change username done in 0.021837
--
[:error, "Invalid auth token / token not found"]
1-11 :: change username done in 0.022213
--
[:error, "Invalid auth token / token not found"]
1-14 :: change username done in 0.022441
--
[:object_id, "4e0e21a7df715b0930000017"][:return, "User saved successfully"]
1-17 :: change username done in 0.950399
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment