Revision 86fb12c1
Added by Ohad Levy almost 12 years ago
- ID 86fb12c1e1009385163d2d255ae6e519f18ea452
Gemfile | ||
---|---|---|
gem 'net-ldap'
|
||
gem "safemode", "~> 1.0.1"
|
||
gem 'uuidtools'
|
||
gem "restapi", :git => "git://github.com/Katello/rails-restapi.git", :branch => "katello"
|
||
gem 'rabl'
|
||
# Previous versions collide with Environment model
|
||
gem "ruby_parser", ">= 2.3.1"
|
Rakefile | ||
---|---|---|
require 'rake'
|
||
include Rake::DSL
|
||
|
||
if Rails.env.test?
|
||
require 'single_test'
|
||
SingleTest.load_tasks
|
||
end
|
||
|
||
Foreman::Application.load_tasks
|
app/controllers/api/base_controller.rb | ||
---|---|---|
#TODO: inherit from application controller after cleanup
|
||
class BaseController < ActionController::Base
|
||
|
||
before_filter :set_default_response_format
|
||
before_filter :authorize
|
||
|
||
before_filter :set_default_response_format, :authorize
|
||
|
||
respond_to :json
|
||
|
||
def process_error options = {}
|
||
|
||
def process_error options = { }
|
||
|
||
options[:json_code] ||= :unprocessable_entity
|
||
|
||
|
||
errors = if options[:error]
|
||
options[:error]
|
||
else
|
||
options[:object] ||= get_resource || raise("No error to process")
|
||
if options[:object].respond_to?(:errors)
|
||
logger.info "Failed to save: #{options[:object].errors.full_messages.join(", ")}"
|
||
options[:object].errors.full_messages
|
||
else
|
||
raise("No error to process")
|
||
end
|
||
end
|
||
options[:error]
|
||
else
|
||
options[:object] ||= get_resource || raise("No error to process")
|
||
if options[:object].respond_to?(:errors)
|
||
#TODO JSON resposne should include the real errors, not the pretty full messages
|
||
logger.info "Failed to save: #{options[:object].errors.full_messages.join(", ")}"
|
||
options[:object].errors.full_messages
|
||
else
|
||
raise("No error to process")
|
||
end
|
||
end
|
||
|
||
# set 403 status on permission errors
|
||
if errors.any? { |error| error =~ /You do not have permission/ }
|
||
options[:json_code] = :forbidden
|
||
end
|
||
|
||
render :json => {"errors" => errors} , :status => options[:json_code]
|
||
render :json => { "errors" => errors }, :status => options[:json_code]
|
||
end
|
||
|
||
def get_resource
|
||
def get_resource
|
||
instance_variable_get(:"@#{controller_name.singularize}")
|
||
end
|
||
|
||
|
||
def process_response condition, response = nil
|
||
if condition
|
||
response ||= get_resource
|
||
... | ... | |
end
|
||
end
|
||
|
||
|
||
|
||
# Authorize the user for the requested action
|
||
def authorize(ctrl = params[:controller], action = params[:action])
|
||
|
||
if SETTINGS[:login]
|
||
unless User.current
|
||
user_to_login = nil
|
||
if result = authenticate_with_http_basic { |u, p| user_to_login = u; User.try_to_login(u, p) }
|
||
if result = authenticate_with_http_basic { |u, p| user_to_login = u; User.try_to_login(u, p) }
|
||
User.current = result
|
||
else
|
||
process_error({:error => "Unable to authenticate user %s" % user_to_login, :json_code => :unauthorized})
|
||
process_error({ :error => "Unable to authenticate user %s" % user_to_login, :json_code => :unauthorized })
|
||
return false
|
||
end
|
||
end
|
||
... | ... | |
end
|
||
|
||
def deny_access
|
||
process_error({:error => "Access denied", :json_code => :unauthorized})
|
||
return false
|
||
process_error({ :error => "Access denied", :json_code => :unauthorized })
|
||
false
|
||
end
|
||
|
||
|
||
protected
|
||
# searches for an object based on its name and assign it to an instance variable
|
||
# required for models which implement the to_param method
|
app/controllers/api/v1/base_controller.rb | ||
---|---|---|
module Api
|
||
module V1
|
||
class BaseController < Api::BaseController
|
||
respond_to :json
|
||
end
|
||
end
|
||
end
|
app/controllers/api/v1/bookmarks_controller.rb | ||
---|---|---|
class BookmarksController < BaseController
|
||
before_filter :find_by_name, :only => [:show, :update, :destroy]
|
||
|
||
api :GET, "/bookmarks/", "List all bookmarks."
|
||
def index
|
||
@bookmarks = Bookmark.all
|
||
end
|
||
|
||
api :GET, "/bookmarks/:id/", "Show a bookmark."
|
||
def show
|
||
end
|
||
|
||
api :POST, "/bookmarks/", "Create a bookmark."
|
||
param :bookmark, Hash, :required => true do
|
||
param :name, String, :required => true
|
||
param :controller, String, :required => true
|
||
param :query, String, :required => true
|
||
end
|
||
def create
|
||
@bookmark = Bookmark.new(params[:bookmark])
|
||
process_response @bookmark.save
|
||
end
|
||
|
||
api :PUT, "/bookmarks/:id/", "Update a bookmark."
|
||
param :bookmark, Hash, :required => true do
|
||
param :name, String
|
||
param :controller, String
|
||
param :query, String
|
||
end
|
||
def update
|
||
process_response @bookmark.update_attributes(params[:bookmark])
|
||
end
|
||
|
||
api :DELETE, "/bookmarks/:id/", "Delete a bookmark."
|
||
def destroy
|
||
process_response @bookmark.destroy
|
||
end
|
app/controllers/api/v1/operatingsystems_controller.rb | ||
---|---|---|
module Api
|
||
module V1
|
||
class OperatingsystemsController < BaseController
|
||
|
||
|
||
resource_description do
|
||
name 'Operating systems'
|
||
end
|
||
|
||
before_filter :find_by_name, :only => %w{show edit update destroy bootfiles}
|
||
|
||
api :GET, "/operatingsystems/", "List all operating systems."
|
||
def index
|
||
@operatingsystems = Operatingsystem.all
|
||
end
|
||
|
||
api :GET, "/operatingsystems/:id/", "Show an OS."
|
||
def show
|
||
end
|
||
|
||
api :POST, "/operatingsystems/", "Create an OS."
|
||
param :operatingsystem, Hash, :required => true do
|
||
param :name, /\A(\S+)\Z/, :required => true
|
||
param :major, String, :required => true
|
||
param :minor, String, :required => true
|
||
end
|
||
def create
|
||
@operatingsystem = Operatingsystem.new(params[:operatingsystem])
|
||
process_error unless @operatingsystem.save
|
||
process_response @operatingsystem.save
|
||
end
|
||
|
||
api :PUT, "/operatingsystems/:id/", "Update an OS."
|
||
param :operatingsystem, Hash, :required => true do
|
||
param :name, /\A(\S+)\Z/
|
||
param :major, String
|
||
param :minor, String
|
||
end
|
||
def update
|
||
process_error unless @operatingsystem.update_attributes(params[:operatingsystem])
|
||
process_response @operatingsystem.update_attributes(params[:operatingsystem])
|
||
end
|
||
|
||
api :DELETE, "/operatingsystems/:id/", "Delete a bookmark."
|
||
def destroy
|
||
process_error unless @operatingsystem.destroy
|
||
process_response @operatingsystem.destroy
|
||
end
|
||
|
||
api :GET, "/operatingsystems/:id/bootfiles/", "List boot files an OS."
|
||
param :medium, String
|
||
param :architecture, String
|
||
def bootfiles
|
||
medium = Medium.find_by_name(params[:medium])
|
||
arch = Architecture.find_by_name(params[:architecture])
|
app/views/api/v1/operatingsystems/show.json.rabl | ||
---|---|---|
object @operatingsystem
|
||
attributes :name, :id
|
||
|
||
attributes :id, :name, :major, :minor, :family, :release_name
|
app/views/api/v1/operatingsystems/update.json.rabl | ||
---|---|---|
object @operatingsystem
|
||
|
||
extends "api/v1/operatingsystems/show"
|
bundler.d/development.rb | ||
---|---|---|
# To use debugger
|
||
gem "ruby-debug", :platforms => :ruby_18
|
||
gem "ruby-debug19", :platforms => :ruby_19
|
||
gem 'redcarpet'
|
||
end
|
bundler.d/test.rb | ||
---|---|---|
gem 'shoulda', "=3.0.1"
|
||
gem 'rr'
|
||
gem 'rake'
|
||
gem 'redcarpet'
|
||
gem 'single_test'
|
||
end
|
config/initializers/restapi.rb | ||
---|---|---|
Restapi.configure do |config|
|
||
config.app_name = "Foreman"
|
||
config.app_info = "The Foreman is aimed to be a single address for all machines life cycle management."
|
||
config.copyright = ""
|
||
config.api_base_url = "/api"
|
||
config.api_controllers_matcher = "#{Rails.root}/app/controllers/api/v1/*.rb"
|
||
config.ignored_by_recorder = %w[]
|
||
config.doc_base_url = "/apidoc"
|
||
config.use_cache = false #Rails.env.production?
|
||
config.validate = false
|
||
config.reload_controllers = true
|
||
config.markup = Restapi::Markup::Markdown.new
|
||
end
|
||
|
||
# special type of validator: we say that it's not specified
|
||
class UndefValidator < Restapi::Validator::BaseValidator
|
||
|
||
def validate(value)
|
||
true
|
||
end
|
||
|
||
def self.build(param_description, argument, options, block)
|
||
if argument == :undef
|
||
self.new(param_description)
|
||
end
|
||
end
|
||
|
||
def description
|
||
nil
|
||
end
|
||
end
|
||
|
||
class Restapi::Validator::TypeValidator
|
||
def description
|
||
@type.name
|
||
end
|
||
end
|
||
|
||
class Restapi::Validator::HashValidator
|
||
def description
|
||
"Hash"
|
||
end
|
||
end
|
||
|
||
class NumberValidator < Restapi::Validator::BaseValidator
|
||
|
||
def validate(value)
|
||
value.to_s =~ /^(0|[1-9]\d*)$/
|
||
end
|
||
|
||
def self.build(param_description, argument, options, block)
|
||
if argument == :number
|
||
self.new(param_description)
|
||
end
|
||
end
|
||
|
||
def error
|
||
"Parameter #{param_name} expecting to be a number, got: #{@error_value}"
|
||
end
|
||
|
||
def description
|
||
"number."
|
||
end
|
||
end
|
||
|
||
class IdentifierValidator < Restapi::Validator::BaseValidator
|
||
|
||
def validate(value)
|
||
value = value.to_s
|
||
value =~ /\A[\w| |_|-]*\Z/ && value.strip == value && (2..128).include?(value.length)
|
||
end
|
||
|
||
def self.build(param_description, argument, options, block)
|
||
if argument == :identifier
|
||
self.new(param_description)
|
||
end
|
||
end
|
||
|
||
def error
|
||
"Parameter #{param_name} expecting to be an identifier, got: #{@error_value}"
|
||
end
|
||
|
||
def description
|
||
"string from 2 to 128 characters containting only alphanumeric characters, space, '_', '-' with no leading or trailing space.."
|
||
end
|
||
end
|
||
|
||
class BooleanValidator < Restapi::Validator::BaseValidator
|
||
|
||
def validate(value)
|
||
%w[true false].include?(value.to_s)
|
||
end
|
||
|
||
def self.build(param_description, argument, options, block)
|
||
if argument == :bool
|
||
self.new(param_description)
|
||
end
|
||
end
|
||
|
||
def error
|
||
"Parameter #{param_name} expecting to be a boolean value, got: #{@error_value}"
|
||
end
|
||
|
||
def description
|
||
"boolean"
|
||
end
|
||
end
|
config/routes.rb | ||
---|---|---|
resources :tasks, :only => [:show]
|
||
|
||
#### API Namespace from here downwards ####
|
||
|
||
restapi
|
||
|
||
namespace :api, :defaults => {:format => 'json'} do
|
||
scope :module => :v1, :constraints => ApiConstraints.new(:version => 1, :default => true) do
|
||
resources :bookmarks, :except => [:new, :edit]
|
Also available in: Unified diff
cleanup after merge conflict with latest develop branch