server/lib/minicron/hub/middleware/auth.rb
module Minicron
module Hub
module Middleware
class Auth
def initialize(app, options={})
@app = app
@options = options
end
def call(env)
# Get an easier to work with request object
req = Rack::Request.new(env)
# Authenticate API requests using API keys
if api_request?(req.fullpath)
# Get the API Key from the request
api_key = req.env["HTTP_X_API_KEY"]
# Try and find a user that matches the api key
begin
user = api_key ? Minicron::Hub::Model::User.where(api_key: api_key).first : nil
rescue ActiveRecord::RecordNotFound
# TODO: log here?
user = nil
end
if user
# Add the user to the env so we can use it later
env[:user] = user
else
return [
401,
{'Content-Type': 'application/json'},
['{"error": "Invalid API credentials"}']
]
end
# Authenticate the user if the route is protected
elsif protected?(req.fullpath)
# Get the user id from the session
user_id = req.session[:user_id]
# Try and find a user that matches the user id
begin
user = user_id ? Minicron::Hub::Model::User.find(req.session[:user_id]) : nil
rescue ActiveRecord::RecordNotFound
# TODO: log here?
user = nil
end
if user
# Add the user to the env so we can use it later
env[:user] = user
else
# If the user has bad data in their session for some reason, remove it
req.session.delete(:user_id)
return [
301,
{'Location' => "#{Minicron::Transport::Server.get_prefix}/auth/sign-in"},
[]
]
end
end
# Call the next middleware in the chain
status, headers, body = @app.call(env)
[status, headers, body]
end
private
def protected?(path)
# Routes we don't need to enforce auth on
public_routes = ["/auth", "/assets", "/favicon.ico", "/__better_errors"].map do |route|
"#{Minicron::Transport::Server.get_prefix}#{route}"
end
!path.start_with?(*public_routes)
end
def api_request?(path)
path.start_with?("#{Minicron::Transport::Server.get_prefix}/api")
end
end
end
end
end