lib/simpleadmin.rb in simpleadmin-1.4.0 vs lib/simpleadmin.rb in simpleadmin-1.5.0
- old
+ new
@@ -1,7 +1,109 @@
+# frozen_string_literal: true
+
+require 'rack/app'
+require 'sequel'
+require 'bcrypt'
+
require 'simpleadmin/version'
-require 'simpleadmin/engine'
+require 'simpleadmin/config'
+require 'simpleadmin/database_connector'
-require 'simpleadmin/application'
+# Administrative dashboard without wasting time
+#
+# @since 1.0.0
+#
+# @see https://getsimpleadmin.com
module Simpleadmin
+ # API endpoints for integration with cloud version of getsimpleadmin.com
+ #
+ # This is used, Rack conception to connect it in any popular web frameworks
+ # like Ruby on Rails, Hanami, Sinatra and etc.
+ #
+ # @since 1.0.0
+ #
+ # @example
+ #
+ # # config/routes.rb
+ # Rails.application.routes.draw do
+ # mount Simpleadmin::Application, at: 'simpleadmin'
+ # end
+ class Application < Rack::App
+ WIDGETS = %w[quantity week_statistic].freeze
+
+ before { respond_forbidden! if secret_key_invalid? }
+ before { respond_forbidden! unless current_path?('/v1/tables') || allowed_table? }
+
+ namespace '/v1' do
+ get '/widgets/:widget_name' do
+ respond_forbidden!(message: 'Nonexistent widget') unless WIDGETS.include?(params['widget_name'])
+
+ client.public_send(params['widget_name'], params['table_name'])
+ end
+
+ get '/tables' do
+ client.tables
+ end
+
+ get '/tables/:table_name' do
+ client.table_columns(params['table_name'])
+ end
+
+ get '/resources' do
+ client.resources(params.values_at('table_name', 'table_fields', 'per_page',
+ 'page', 'query', 'model_attributes', 'sort'))
+ end
+
+ get '/resources/:id' do
+ client.resource(params['id'], params['table_name'], params['table_fields'])
+ end
+
+ post '/resources' do
+ client.create_resource(request_body_params['table_name'], request_body_params['resource'])
+ end
+
+ patch '/resources/:id' do
+ client.update_resource(request_body_params['table_name'], params['id'], request_body_params['resource'])
+ end
+
+ delete '/resources/:id' do
+ client.destroy_resouce(request_body_params['table_name'], params['id'])
+ end
+ end
+
+ private
+
+ def client
+ @client ||= connector.client
+ end
+
+ def respond_forbidden!(message: 'Forbidden')
+ response.status = 403
+ response.write(message)
+
+ finish!
+ end
+
+ def request_body_params
+ @request_body_params ||= Rack::Utils.parse_nested_query(request.body.read)
+ end
+
+ def connector
+ @connector ||= DatabaseConnector.new(
+ database_credentials: Config.database_credentials
+ )
+ end
+
+ def allowed_table?
+ Config.allowed_table?(params['table_name'] || request_body_params['table_name'])
+ end
+
+ def secret_key_invalid?
+ BCrypt::Password.new(request.get_header('HTTP_SIMPLEADMIN_SECRET_KEY')) != ENV['SIMPLE_ADMIN_SECRET_KEY']
+ end
+
+ def current_path?(path)
+ request.path_info == path
+ end
+ end
end