Created
November 18, 2012 21:16
-
-
Save andytill/4107546 to your computer and use it in GitHub Desktop.
A Sinatra proxy to be used over a neo4j ReST API
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
# web proxy for a neo4j database, using Heroku but could be easily modified for anything else | |
# this code is a modified version of the code found here https://github.com/akollegger/nosql-now/blob/master/web.rb | |
# the main changes are... | |
# - authentication required for modification, although viewing is allowed without authentication (auth can be added by calling protected! in the get method) | |
# - the domain returned in the data is replaced with the proxy domain instead of being removed which was causing errors in the java jersey library | |
# - modified post routing, this wasn't catching all POST requests | |
require 'sinatra' | |
require 'rest-client' | |
require 'json' | |
neo4j_db_url = ENV['NEO4J_URL'] || "http://localhost:7474" | |
neo4j_db_url_noauth = neo4j_db_url.gsub /http:\/\/\w+:\w+@/, "http://" | |
# SECRET STUFF! put your user name and password and URL for the Heroku app here | |
neo4j_user = "" | |
neo4j_password = "" | |
HEROKU_APP_HOST = "" | |
REPLACE_DB_HOST = /(#{neo4j_db_url})|(#{neo4j_db_url_noauth})/ | |
REST = RestClient::Resource.new neo4j_db_url, neo4j_user, neo4j_password | |
helpers do | |
def protected! | |
unless authorized? | |
response['WWW-Authenticate'] = %(Basic realm="Restricted Area") | |
throw(:halt, [401, "Not authorized\n"]) | |
end | |
end | |
def authorized? | |
@auth ||= Rack::Auth::Basic::Request.new(request.env) | |
@auth.provided? && @auth.basic? && @auth.credentials && @auth.credentials == [neo4j_user, neo4j_password] | |
end | |
end | |
get '/' do | |
if request.accept.include?("application/json") || request.accept.include?("text/javascript") | |
pass_to_neo4j | |
else | |
# TODO return not found? | |
end | |
end | |
get /\/webadmin.*/ do | |
protected! | |
pass_to_neo4j | |
end | |
get /\/db\/.*/ do | |
pass_to_neo4j | |
end | |
options /\/db\/.*/ do | |
pass_to_neo4j | |
end | |
post '/db/data/*' do | |
protected! | |
pass_to_neo4j | |
end | |
post "/db/manage/server/console/" do | |
protected! | |
data = JSON.parse request.body.read | |
if data["engine"] == "gremlin" | |
content_type "application/json" | |
["Security-Constraint: Gremlin is DISABLED", ""].to_json | |
else | |
pass_to_neo4j data.to_json | |
end | |
end | |
post "/db/manage/server/jmx/query" do | |
protected! | |
pass_to_neo4j | |
end | |
def pass_to_neo4j(data=nil) | |
request_method = request.request_method | |
#puts "#{request_method} #{request.path}" | |
request_method = request_method.downcase.to_sym | |
request_headers = { | |
:accept => "application/json", | |
:content_type => "application/json", | |
:cookies => request.cookies | |
} | |
if request_method == :get | |
proxy_response = REST[request.path].get(request_headers) | |
else | |
data = data || request.body.read | |
proxy_response = REST[request.path].send(request_method, data, request_headers) | |
end | |
cookies = proxy_response.cookies | |
response.set_cookie("JSESSIONID", :value => cookies["JSESSIONID"], :path => cookies["Path"]) if cookies | |
content_type proxy_response.headers[:content_type] | |
if %W(application/json application/x-javascript text/css text/html).include? proxy_response.headers[:content_type] | |
# replace the host name of the neo4j database with the host name of the proxy so we're in the middle of future calls | |
proxy_response.gsub REPLACE_DB_HOST, HEROKU_APP_HOST | |
else | |
proxy_response | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment