refinerycms-api 1.0.0.beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|