module Rhoconnect # Constants # CURRENT_REQUEST = 'CURRENT_REQUEST'.freeze CURRENT_APP = 'CURRENT_APP'.freeze CURRENT_USER = 'CURRENT_USER'.freeze # header names, in the form of server's HTTP variables # X-RhoConnect-API-TOKEN API_TOKEN_HEADER = 'HTTP_X_RHOCONNECT_API_TOKEN'.freeze # X-RhoConnect-CLIENT-ID CLIENT_ID_HEADER = 'HTTP_X_RHOCONNECT_CLIENT_ID'.freeze # old-way admin routes OLD_API_URI_REGEXP = /\/api\// # new way system routes will be: # /rc//system/ # /rc/// SYSTEM_API_URI_REGEXP = /\/rc\/\w+\/\w+/ # also, /app/v1//push_* are still remain Admin routes PUSH_API_URI_REGEXP = /\/app\/\w+\/\w+\/push\w+/ # also, /app/v1//fast_* are still remain Admin routes FAST_CUD_API_URI_REGEXP = /\/app\/\w+\/\w+\/fast\w+/ def is_clients_non_admin_route(env) # FIXME : not all routes for Clients protocol are admin routes full_path = env['SCRIPT_NAME'] + env['PATH_INFO'] /\/rc\/\w+\/clients/.match(full_path) and not ((env[CURRENT_REQUEST].request_method == 'GET') || (env[CURRENT_REQUEST].request_method == 'POST' and /\/rc\/\w+\/clients\/\w+\/sources/.match(full_path))) end def is_client_route(env) # FIXME - once Controllers concept is implemented # remove this - since the inclusion of Admin Middleware # will automatically imply what routes are Admin and which are not full_path = env['SCRIPT_NAME'] + env['PATH_INFO'] # login route and index route doesn't need a token return true if /\/login/.match(full_path) || full_path == '/' # old application routes are not admin return true if full_path == '/application' return true if full_path == '/api/application' return true if /\/application\//.match(full_path) # some of the clients routes are not admin return true if is_clients_non_admin_route(env) # push_objects and push_deletes methods are admin return false if PUSH_API_URI_REGEXP.match(full_path) # fast_insert/update/delete methods are admin return false if FAST_CUD_API_URI_REGEXP.match(full_path) # old api methods + every method in /rc/v1/app namespace return true if /\/app\//.match(full_path) # all other methods in the /rc/v1/ are admin routes return false if SYSTEM_API_URI_REGEXP.match(full_path) # all old /api methods are admin as well return false if OLD_API_URI_REGEXP.match(full_path) # everything else should not be admin true end def is_admin_route(env) not is_client_route(env) end def is_login_required(env) # FIXME - once Controllers concept is implemented # remove this - since the inclusion of LoginRequired Middleware # will automatically imply what routes require Login and which are not full_path = env['SCRIPT_NAME'] + env['PATH_INFO'] return false if full_path == '/' or /login/.match(full_path) # all methods in app namespace return true if /\/app\//.match(full_path) # old application routes are not admin return true if full_path == '/application' return true if full_path == '/api/application' return true if /\/application\//.match(full_path) # also methods that operate on clients should have an associated user return true if is_clients_non_admin_route(env) # for every other route login is not required # because it's either an admin route (where api_user must be supplied anyway) # or it's a custom route extending RhoConnect server false end def extract_current_user(env) user = nil if User.is_exist?(env['rack.session'][:login]) user = User.load(env['rack.session'][:login]) end if user and (user.admin == 1 || env['rack.session'][:app_name] == APP_NAME) user else nil end end def extract_api_user(env) r = env[CURRENT_REQUEST] # API_TOKEN is either a param or a header u = ApiToken.load(env[API_TOKEN_HEADER]) u = ApiToken.load(r.params['api_token']) unless u raise Rhoconnect::ApiException.new(422, "No API token provided") unless u u.user end end