refinerycms-api 1.0.0.beta
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/.rbenv-gemsets +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +12 -0
- data/Gemfile +57 -0
- data/LICENSE +27 -0
- data/Rakefile +21 -0
- data/app/controllers/refinery/api/base_controller.rb +174 -0
- data/app/controllers/refinery/api/v1/blog/posts_controller.rb +78 -0
- data/app/controllers/refinery/api/v1/images_controller.rb +76 -0
- data/app/controllers/refinery/api/v1/inquiries/inquiries_controller.rb +69 -0
- data/app/controllers/refinery/api/v1/pages_controller.rb +77 -0
- data/app/controllers/refinery/api/v1/resources_controller.rb +66 -0
- data/app/decorators/models/refinery/authentication/devise/user_decorator.rb +5 -0
- data/app/helpers/refinery/api/api_helpers.rb +54 -0
- data/app/models/concerns/refinery/user_api_authentication.rb +19 -0
- data/app/models/refinery/ability.rb +59 -0
- data/app/views/refinery/api/errors/gateway_error.v1.rabl +2 -0
- data/app/views/refinery/api/errors/invalid_api_key.v1.rabl +2 -0
- data/app/views/refinery/api/errors/invalid_resource.v1.rabl +3 -0
- data/app/views/refinery/api/errors/must_specify_api_key.v1.rabl +2 -0
- data/app/views/refinery/api/errors/not_found.v1.rabl +2 -0
- data/app/views/refinery/api/errors/unauthorized.v1.rabl +2 -0
- data/app/views/refinery/api/v1/blog/posts/index.v1.rabl +5 -0
- data/app/views/refinery/api/v1/blog/posts/new.v1.rabl +3 -0
- data/app/views/refinery/api/v1/blog/posts/show.v1.rabl +5 -0
- data/app/views/refinery/api/v1/images/index.v1.rabl +5 -0
- data/app/views/refinery/api/v1/images/new.v1.rabl +3 -0
- data/app/views/refinery/api/v1/images/show.v1.rabl +6 -0
- data/app/views/refinery/api/v1/inquiries/inquiries/index.v1.rabl +5 -0
- data/app/views/refinery/api/v1/inquiries/inquiries/new.v1.rabl +3 -0
- data/app/views/refinery/api/v1/inquiries/inquiries/show.v1.rabl +5 -0
- data/app/views/refinery/api/v1/pages/index.v1.rabl +8 -0
- data/app/views/refinery/api/v1/pages/new.v1.rabl +3 -0
- data/app/views/refinery/api/v1/pages/pages.v1.rabl +5 -0
- data/app/views/refinery/api/v1/pages/show.v1.rabl +9 -0
- data/app/views/refinery/api/v1/resources/index.v1.rabl +5 -0
- data/app/views/refinery/api/v1/resources/new.v1.rabl +3 -0
- data/app/views/refinery/api/v1/resources/show.v1.rabl +6 -0
- data/bin/rails +5 -0
- data/bin/rake +21 -0
- data/bin/rspec +22 -0
- data/bin/spring +18 -0
- data/config/initializers/metal_load_paths.rb +1 -0
- data/config/locales/en.yml +27 -0
- data/config/routes.rb +24 -0
- data/db/migrate/20160501141738_add_api_key_to_refinery_authentication_devise_users.rb +8 -0
- data/lib/generators/refinery/api/api_generator.rb +16 -0
- data/lib/generators/refinery/api/templates/config/initializers/refinery/api.rb.erb +7 -0
- data/lib/refinery/api.rb +29 -0
- data/lib/refinery/api/configuration.rb +32 -0
- data/lib/refinery/api/controller_helpers/auth.rb +76 -0
- data/lib/refinery/api/controller_helpers/strong_parameters.rb +37 -0
- data/lib/refinery/api/controller_setup.rb +20 -0
- data/lib/refinery/api/engine.rb +52 -0
- data/lib/refinery/api/responders.rb +11 -0
- data/lib/refinery/api/responders/rabl_template.rb +30 -0
- data/lib/refinery/api/testing_support/caching.rb +10 -0
- data/lib/refinery/api/testing_support/helpers.rb +44 -0
- data/lib/refinery/api/testing_support/setup.rb +16 -0
- data/lib/refinery/permitted_attributes.rb +40 -0
- data/lib/refinery/responder.rb +45 -0
- data/lib/refinerycms-api.rb +3 -0
- data/readme.md +69 -0
- data/refinerycms_api.gemspec +22 -0
- data/script/rails +9 -0
- data/spec/controllers/refinery/api/base_controller_spec.rb +73 -0
- data/spec/controllers/refinery/api/v1/blog/posts_controller_spec.rb +140 -0
- data/spec/controllers/refinery/api/v1/images_controller_spec.rb +93 -0
- data/spec/controllers/refinery/api/v1/inquiries/inquiries_controller_spec.rb +126 -0
- data/spec/controllers/refinery/api/v1/pages_controller_spec.rb +150 -0
- data/spec/controllers/refinery/api/v1/resources_controller_spec.rb +94 -0
- data/spec/fixtures/refinery_is_awesome.txt +1 -0
- data/spec/fixtures/thinking-cat.jpg +0 -0
- data/spec/models/refinery/user_spec.rb +23 -0
- data/spec/requests/rabl_cache_spec.rb +17 -0
- data/spec/requests/ransackable_attributes_spec.rb +80 -0
- data/spec/requests/version_spec.rb +23 -0
- data/spec/shared_examples/protect_product_actions.rb +17 -0
- data/spec/spec_helper.rb +77 -0
- data/spec/support/controller_hacks.rb +33 -0
- data/spec/support/database_cleaner.rb +14 -0
- data/spec/support/have_attributes_matcher.rb +9 -0
- data/tasks/refinery_api.rake +14 -0
- data/tasks/rspec.rake +4 -0
- metadata +240 -0
@@ -0,0 +1,69 @@
|
|
1
|
+
if defined?(Refinery::Inquiries)
|
2
|
+
module Refinery
|
3
|
+
module Api
|
4
|
+
module V1
|
5
|
+
module Inquiries
|
6
|
+
class InquiriesController < Refinery::Api::BaseController
|
7
|
+
|
8
|
+
def index
|
9
|
+
if params[:ids]
|
10
|
+
@inquiries = Refinery::Inquiries::Inquiry.
|
11
|
+
accessible_by(current_ability, :read).
|
12
|
+
where(id: params[:ids].split(','))
|
13
|
+
else
|
14
|
+
@inquiries = Refinery::Inquiries::Inquiry.
|
15
|
+
accessible_by(current_ability, :read).
|
16
|
+
# ransack(params[:q]).result
|
17
|
+
order("created_at DESC")
|
18
|
+
end
|
19
|
+
|
20
|
+
respond_with(@inquiries)
|
21
|
+
end
|
22
|
+
|
23
|
+
def show
|
24
|
+
@inquiry = inquiry
|
25
|
+
respond_with(@inquiry)
|
26
|
+
end
|
27
|
+
|
28
|
+
def new
|
29
|
+
end
|
30
|
+
|
31
|
+
def create
|
32
|
+
authorize! :create, ::Refinery::Inquiries::Inquiry
|
33
|
+
@inquiry = Refinery::Inquiries::Inquiry.new(inquiry_params)
|
34
|
+
|
35
|
+
if @inquiry.save
|
36
|
+
respond_with(@inquiry, status: 201, default_template: :show)
|
37
|
+
else
|
38
|
+
invalid_resource!(@inquiry)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def destroy
|
43
|
+
authorize! :destroy, inquiry
|
44
|
+
inquiry.destroy
|
45
|
+
respond_with(inquiry, status: 204)
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def inquiry
|
51
|
+
@inquiry ||= Refinery::Inquiries::Inquiry.
|
52
|
+
accessible_by(current_ability, :read).
|
53
|
+
find(params[:id])
|
54
|
+
end
|
55
|
+
|
56
|
+
def inquiry_params
|
57
|
+
if params[:inquiry] && !params[:inquiry].empty?
|
58
|
+
params.require(:inquiry).permit(permitted_inquiries_inquiry_attributes)
|
59
|
+
else
|
60
|
+
{}
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Refinery
|
2
|
+
module Api
|
3
|
+
module V1
|
4
|
+
class PagesController < Refinery::Api::BaseController
|
5
|
+
|
6
|
+
def index
|
7
|
+
if params[:ids]
|
8
|
+
@pages = Refinery::Page.
|
9
|
+
includes(:translations, :children).
|
10
|
+
accessible_by(current_ability, :read).
|
11
|
+
where(id: params[:ids].split(','))
|
12
|
+
else
|
13
|
+
@pages = Refinery::Page.
|
14
|
+
includes(:translations, :children).
|
15
|
+
accessible_by(current_ability, :read).
|
16
|
+
# ransack(params[:q]).result
|
17
|
+
order(:lft)
|
18
|
+
end
|
19
|
+
|
20
|
+
respond_with(@pages)
|
21
|
+
end
|
22
|
+
|
23
|
+
def show
|
24
|
+
@page = page
|
25
|
+
respond_with(@page)
|
26
|
+
end
|
27
|
+
|
28
|
+
def new
|
29
|
+
end
|
30
|
+
|
31
|
+
def create
|
32
|
+
authorize! :create, Page
|
33
|
+
@page = Refinery::Page.new(page_params)
|
34
|
+
|
35
|
+
if @page.save
|
36
|
+
respond_with(@page, status: 201, default_template: :show)
|
37
|
+
else
|
38
|
+
invalid_resource!(@page)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def update
|
43
|
+
authorize! :update, page
|
44
|
+
if page.update_attributes(page_params)
|
45
|
+
respond_with(page, status: 200, default_template: :show)
|
46
|
+
else
|
47
|
+
invalid_resource!(page)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def destroy
|
52
|
+
authorize! :destroy, page
|
53
|
+
page.destroy
|
54
|
+
respond_with(page, status: 204)
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def page
|
60
|
+
@page ||= Refinery::Page.
|
61
|
+
includes(:translations, :parts).
|
62
|
+
accessible_by(current_ability, :read).
|
63
|
+
find(params[:id])
|
64
|
+
end
|
65
|
+
|
66
|
+
def page_params
|
67
|
+
if params[:page] && !params[:page].empty?
|
68
|
+
params.require(:page).permit(permitted_page_attributes)
|
69
|
+
else
|
70
|
+
{}
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module Refinery
|
2
|
+
module Api
|
3
|
+
module V1
|
4
|
+
class ResourcesController < Refinery::Api::BaseController
|
5
|
+
def index
|
6
|
+
if params[:ids]
|
7
|
+
@resources = Refinery::Resource.
|
8
|
+
includes(:translations).
|
9
|
+
accessible_by(current_ability, :read).
|
10
|
+
where(id: params[:ids].split(','))
|
11
|
+
else
|
12
|
+
@resources = Refinery::Resource.
|
13
|
+
includes(:translations).
|
14
|
+
accessible_by(current_ability, :read).
|
15
|
+
# load.ransack(params[:q]).result
|
16
|
+
all
|
17
|
+
end
|
18
|
+
respond_with(@resources)
|
19
|
+
end
|
20
|
+
|
21
|
+
def show
|
22
|
+
@resource = Refinery::Resource.
|
23
|
+
includes(:translations).
|
24
|
+
accessible_by(current_ability, :read).
|
25
|
+
find(params[:id])
|
26
|
+
respond_with(@resource)
|
27
|
+
end
|
28
|
+
|
29
|
+
def new
|
30
|
+
end
|
31
|
+
|
32
|
+
def create
|
33
|
+
authorize! :create, Resource
|
34
|
+
@resources = Refinery::Resource.create_resources(resource_params)
|
35
|
+
|
36
|
+
if @resources.all?(&:valid?)
|
37
|
+
respond_with(@resources, status: 201, default_template: :show)
|
38
|
+
else
|
39
|
+
invalid_resource!(@resources)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def update
|
44
|
+
@resource = Refinery::Resource.accessible_by(current_ability, :update).find(params[:id])
|
45
|
+
if @resource.update_attributes(resource_params)
|
46
|
+
respond_with(@resource, default_template: :show)
|
47
|
+
else
|
48
|
+
invalid_resource!(@resource)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def destroy
|
53
|
+
@resource = Refinery::Resource.accessible_by(current_ability, :destroy).find(params[:id])
|
54
|
+
@resource.destroy
|
55
|
+
respond_with(@resource, status: 204)
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def resource_params
|
61
|
+
params.require(:resource).permit(permitted_resource_attributes)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Refinery
|
2
|
+
module Api
|
3
|
+
module ApiHelpers
|
4
|
+
ATTRIBUTES = [
|
5
|
+
:image_attributes,
|
6
|
+
:page_attributes,
|
7
|
+
:page_part_attributes,
|
8
|
+
:resource_attributes,
|
9
|
+
:blog_post_attributes,
|
10
|
+
:inquiries_inquiry_attributes
|
11
|
+
]
|
12
|
+
|
13
|
+
mattr_reader *ATTRIBUTES
|
14
|
+
|
15
|
+
def required_fields_for(model)
|
16
|
+
required_fields = model._validators.select do |field, validations|
|
17
|
+
validations.any? { |v| v.is_a?(ActiveModel::Validations::PresenceValidator) }
|
18
|
+
end.map(&:first) # get fields that are invalid
|
19
|
+
# Permalinks presence is validated, but are really automatically generated
|
20
|
+
# Therefore we shouldn't tell API clients that they MUST send one through
|
21
|
+
required_fields.map!(&:to_s).delete("permalink")
|
22
|
+
# Do not require slugs, either
|
23
|
+
required_fields.delete("slug")
|
24
|
+
required_fields
|
25
|
+
end
|
26
|
+
|
27
|
+
@@image_attributes = [
|
28
|
+
{ image: [] }, :image_size, :image_title, :image_alt
|
29
|
+
]
|
30
|
+
|
31
|
+
@@page_attributes = [
|
32
|
+
:browser_title, :draft, :link_url, :menu_title, :meta_description,
|
33
|
+
:parent_id, :skip_to_first_child, :show_in_menu, :title, :view_template,
|
34
|
+
:layout_template, :custom_slug, parts_attributes: [:id, :title, :slug, :body, :position]
|
35
|
+
]
|
36
|
+
|
37
|
+
@@page_part_attributes = [
|
38
|
+
:title, :slug, :body, :locale
|
39
|
+
]
|
40
|
+
|
41
|
+
@@resource_attributes = [
|
42
|
+
:resource_title, { file: [] }
|
43
|
+
]
|
44
|
+
|
45
|
+
@@blog_post_attributes = [
|
46
|
+
:title, :body, :custom_teaser, :tag_list,
|
47
|
+
:draft, :published_at, :custom_url, :user_id, :username, :browser_title,
|
48
|
+
:meta_description, :source_url, :source_url_title, category_ids: []
|
49
|
+
]
|
50
|
+
|
51
|
+
@@inquiries_inquiry_attributes = [:name, :phone, :message, :email]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Refinery
|
2
|
+
module UserApiAuthentication
|
3
|
+
def generate_refinery_api_key!
|
4
|
+
self.refinery_api_key = generate_refinery_api_key
|
5
|
+
save!
|
6
|
+
end
|
7
|
+
|
8
|
+
def clear_refinery_api_key!
|
9
|
+
self.refinery_api_key = nil
|
10
|
+
save!
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def generate_refinery_api_key
|
16
|
+
SecureRandom.hex(24)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# Implementation class for Cancan gem. Instead of overriding this class, consider adding new permissions
|
2
|
+
# using the special +register_ability+ method which allows extensions to add their own abilities.
|
3
|
+
#
|
4
|
+
# See http://github.com/ryanb/cancan for more details on cancan.
|
5
|
+
require 'cancan'
|
6
|
+
module Refinery
|
7
|
+
class Ability
|
8
|
+
include CanCan::Ability
|
9
|
+
|
10
|
+
class_attribute :abilities
|
11
|
+
self.abilities = Set.new
|
12
|
+
|
13
|
+
# Allows us to go beyond the standard cancan initialize method which makes it difficult for engines to
|
14
|
+
# modify the default +Ability+ of an application. The +ability+ argument must be a class that includes
|
15
|
+
# the +CanCan::Ability+ module. The registered ability should behave properly as a stand-alone class
|
16
|
+
# and therefore should be easy to test in isolation.
|
17
|
+
def self.register_ability(ability)
|
18
|
+
self.abilities.add(ability)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.remove_ability(ability)
|
22
|
+
self.abilities.delete(ability)
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize(user)
|
26
|
+
self.clear_aliased_actions
|
27
|
+
|
28
|
+
# override cancan default aliasing (we don't want to differentiate between read and index)
|
29
|
+
alias_action :delete, to: :destroy
|
30
|
+
alias_action :edit, to: :update
|
31
|
+
alias_action :new, to: :create
|
32
|
+
alias_action :new_action, to: :create
|
33
|
+
alias_action :show, to: :read
|
34
|
+
alias_action :index, :read, to: :display
|
35
|
+
alias_action :create, :update, :destroy, to: :modify
|
36
|
+
|
37
|
+
user ||= Refinery::Api.user_class.new
|
38
|
+
|
39
|
+
if user.respond_to?(:has_role?) && user.has_role?('superuser')
|
40
|
+
can :manage, :all
|
41
|
+
else
|
42
|
+
can :display, Image
|
43
|
+
can :display, Page
|
44
|
+
can :display, Resource
|
45
|
+
can :display, Blog::Post if defined?(Refinery::Blog)
|
46
|
+
can :display, Inquiries::Inquiry if defined?(Refinery::Inquiries)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Include any abilities registered by extensions, etc.
|
50
|
+
Ability.abilities.each do |clazz|
|
51
|
+
ability = clazz.send(:new, user)
|
52
|
+
@rules = rules + ability.send(:rules)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Protect admin role
|
56
|
+
cannot [:update, :destroy], Role, name: ['superuser'] if defined?(Role)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|