From ad4c823251b918e38be5a939ed4d605a1f8af78e Mon Sep 17 00:00:00 2001 From: Anton Martynov Date: Wed, 18 Feb 2015 13:15:25 +0300 Subject: [PATCH] sinatra methods_with_headers --- devops-service/db/mongo/models/user.rb | 2 +- devops-service/devops-service.rb | 3 +- devops-service/devops_config.rb | 2 + devops-service/helpers/version_2.rb | 32 ------ devops-service/routes/v2.0/flavor.rb | 8 +- devops-service/routes/v2.0/handlers/flavor.rb | 2 + devops-service/routes/v2.0/handlers/image.rb | 8 ++ devops-service/routes/v2.0/image.rb | 30 +----- .../sinatra/methods_with_headers.rb | 99 +++++++++++++++++++ 9 files changed, 118 insertions(+), 68 deletions(-) create mode 100644 devops-service/sinatra/methods_with_headers.rb diff --git a/devops-service/db/mongo/models/user.rb b/devops-service/db/mongo/models/user.rb index ffe204a..f917d31 100644 --- a/devops-service/db/mongo/models/user.rb +++ b/devops-service/db/mongo/models/user.rb @@ -87,7 +87,7 @@ class User < MongoModel end private - def privileges_with_value v, options={} + def privileges_with_value value, options={} privileges = {} [ 'flavor', diff --git a/devops-service/devops-service.rb b/devops-service/devops-service.rb index abc1074..86e9c4d 100644 --- a/devops-service/devops-service.rb +++ b/devops-service/devops-service.rb @@ -22,6 +22,8 @@ require_relative "client" require_relative "report" require_relative "version" +require_relative "sinatra/methods_with_headers" + class DevopsService include Wisper::Publisher @@ -81,7 +83,6 @@ class DevopsService send(:generate_method, name, &block) end - end require "wisper_fix" diff --git a/devops-service/devops_config.rb b/devops-service/devops_config.rb index 1b6502d..7df0711 100644 --- a/devops-service/devops_config.rb +++ b/devops-service/devops_config.rb @@ -2,6 +2,8 @@ require "socket" class DevopsConfig + OBJECT_NAME = /[\w\-]+/ + @@config = nil class << self diff --git a/devops-service/helpers/version_2.rb b/devops-service/helpers/version_2.rb index 6e0418c..643638b 100644 --- a/devops-service/helpers/version_2.rb +++ b/devops-service/helpers/version_2.rb @@ -26,38 +26,6 @@ module Devops true end - # Check request headers - def check_headers *headers - ha = (headers.empty? ? [:accept, :content_type] : headers) - ha.each do |h| - case h - when :accept, "accept" - accept_json - when :content_type, "content_type" - request_json - end - end - end - - # Check Accept header - # - # Can client works with JSON? - def accept_json - logger.debug(request.accept) - unless request.accept? 'application/json' - response.headers['Accept'] = 'application/json' - halt_response("Accept header should contains 'application/json' type", 406) - end - rescue NoMethodError => e - #error in sinatra 1.4.4 (https://github.com/sinatra/sinatra/issues/844, https://github.com/sinatra/sinatra/pull/805) - response.headers['Accept'] = 'application/json' - halt_response("Accept header should contains 'application/json' type", 406) - end - - # Check Content-Type header - def request_json - halt_response("Content-Type should be 'application/json'", 415) if request.media_type.nil? or request.media_type != 'application/json' - end def check_provider provider list = ::Provider::ProviderFactory.providers diff --git a/devops-service/routes/v2.0/flavor.rb b/devops-service/routes/v2.0/flavor.rb index 92655c5..d3abcf7 100644 --- a/devops-service/routes/v2.0/flavor.rb +++ b/devops-service/routes/v2.0/flavor.rb @@ -4,12 +4,6 @@ module Devops module FlavorRoutes def self.registered(app) - - app.before "/flavors/:provider" do - check_headers :accept - check_privileges("flavor", "r") - check_provider(params[:provider]) - end # Get list of flavors for :provider # # * *Request* @@ -37,7 +31,7 @@ module Devops # "disk": 20 # } # ] - app.get "/flavors/:provider", &Devops::Version2_0::Handler::Flavor.get_flavors + app.get_with_headers "/flavors/:provider", :headers => [:accept], &Devops::Version2_0::Handler::Flavor.get_flavors puts "Flavor routes initialized" end diff --git a/devops-service/routes/v2.0/handlers/flavor.rb b/devops-service/routes/v2.0/handlers/flavor.rb index 0e30ab2..c71b2d1 100644 --- a/devops-service/routes/v2.0/handlers/flavor.rb +++ b/devops-service/routes/v2.0/handlers/flavor.rb @@ -6,6 +6,8 @@ module Devops class Flavor def self.get_flavors lambda { + check_privileges("flavor", "r") + check_provider(params[:provider]) p = ::Provider::ProviderFactory.get params[:provider] json p.flavors } diff --git a/devops-service/routes/v2.0/handlers/image.rb b/devops-service/routes/v2.0/handlers/image.rb index 256d4ca..2c74537 100644 --- a/devops-service/routes/v2.0/handlers/image.rb +++ b/devops-service/routes/v2.0/handlers/image.rb @@ -10,6 +10,8 @@ module Devops def self.get_images lambda { + check_privileges("image", "r") + check_provider(params[:provider]) if params[:provider] images = settings.mongo.images(params[:provider]) json(images.map {|i| i.to_hash}) } @@ -17,18 +19,22 @@ module Devops def self.get_provider_images lambda { + check_privileges("image", "r") + check_provider(params[:provider]) json get_images(settings.mongo, params[:provider]) } end def self.get_image lambda { + check_privileges("image", "r") json settings.mongo.image(params[:image_id]) } end def self.create_image lambda { + check_privileges("image", "w") image = create_object_from_json_body settings.mongo.image_insert Image.new(image) create_response "Created", nil, 201 @@ -37,6 +43,7 @@ module Devops def self.update_image lambda { + check_privileges("image", "w") settings.mongo.image params[:image_id] image = Image.new(create_object_from_json_body) image.id = params[:image_id] @@ -47,6 +54,7 @@ module Devops def self.delete_image lambda { + check_privileges("image", "w") projects = settings.mongo.projects_by_image params[:image_id] unless projects.empty? ar = [] diff --git a/devops-service/routes/v2.0/image.rb b/devops-service/routes/v2.0/image.rb index 028d0d8..e6bf3ea 100644 --- a/devops-service/routes/v2.0/image.rb +++ b/devops-service/routes/v2.0/image.rb @@ -8,11 +8,6 @@ module Devops statistic end - app.before "/images" do - check_headers :accept - check_privileges("image", "r") - check_provider(params[:provider]) if params[:provider] - end # Get devops images list # # * *Request* @@ -32,13 +27,8 @@ module Devops # "id": "36dc7618-4178-4e29-be43-286fbfe90f50" # } # ] - app.get "/images", &Devops::Version2_0::Handler::Image.get_images + app.get "/images", :headers => [:accept], &Devops::Version2_0::Handler::Image.get_images - app.before "/images/provider/:provider" do - check_headers :accept - check_privileges("image", "r") - check_provider(params[:provider]) - end # Get raw images for :provider # # * *Request* @@ -63,18 +53,8 @@ module Devops # "status": "ACTIVE" # } # ] - app.get "/images/provider/:provider", &Devops::Version2_0::Handler::Image.get_provider_images + app.get "/images/provider/:provider", :headers => [:accept], &Devops::Version2_0::Handler::Image.get_provider_images - app.before "/image/:image_id" do - case request.method - when "get" - check_headers :accept - check_privileges("image", "r") - when "delete", "put" - check_headers - check_privileges("image", "w") - end - end # Get devops image by id # # * *Request* @@ -90,12 +70,8 @@ module Devops # "bootstrap_template": null, # "id": "36dc7618-4178-4e29-be43-286fbfe90f50" # } - app.get "/image/:image_id", &Devops::Version2_0::Handler::Image.get_image + app.get "/image/:image_id", :headers => [:accept], &Devops::Version2_0::Handler::Image.get_image - app.before "/image" do - check_headers - check_privileges("image", "w") - end # Create devops image # # * *Request* diff --git a/devops-service/sinatra/methods_with_headers.rb b/devops-service/sinatra/methods_with_headers.rb new file mode 100644 index 0000000..83744f9 --- /dev/null +++ b/devops-service/sinatra/methods_with_headers.rb @@ -0,0 +1,99 @@ +require "sinatra/base" + +module Sinatra + + module HeadersHelpers + + end + + helpers HeadersHelpers + + class Base + class << self + + # TODO: add protect! method + def get_with_headers path, opt={}, &block + headers = opt.delete(:headers) || [] + before path do + check_headers *headers + end + + get path, opt, &block + end + + def post_with_headers path, opt={}, &block + headers = opt.delete(:headers) || [] + before path do + check_headers *headers + end + + post path, opt, &block + + after path do + statistic + end + end + + def put_with_headers path, opt={}, &block + headers = opt.delete(:headers) || [] + before path do + check_headers *headers + end + + put path, opt, &block + + after path do + statistic + end + end + + def delete_with_headers path, opt={}, &block + headers = opt.delete(:headers) || [] + before path do + check_headers *headers + end + + delete path, opt, &block + + after path do + statistic + end + end + end + + # Check request headers + def check_headers *headers + ha = (headers.empty? ? [:accept, :content_type] : headers) + ha.each do |h| + case h + when :accept, "accept" + accept_json + when :content_type, "content_type" + request_json + end + end + end + + # Check Accept header + # + # Can client works with JSON? + def accept_json + logger.debug(request.accept) + unless request.accept? 'application/json' + response.headers['Accept'] = 'application/json' + halt_response("Accept header should contains 'application/json' type", 406) + end + rescue NoMethodError => e + #error in sinatra 1.4.4 (https://github.com/sinatra/sinatra/issues/844, https://github.com/sinatra/sinatra/pull/805) + response.headers['Accept'] = 'application/json' + halt_response("Accept header should contains 'application/json' type", 406) + end + + # Check Content-Type header + def request_json + halt_response("Content-Type should be 'application/json'", 415) if request.media_type.nil? or request.media_type != 'application/json' + end + + + end +end