Skip to content

Commit

Permalink
Add authorization to pages controllers
Browse files Browse the repository at this point in the history
Authorized users can now access unpublished pages as well.
  • Loading branch information
tvdeyen committed Nov 16, 2020
1 parent 9001b67 commit b9ac752
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 14 deletions.
1 change: 1 addition & 0 deletions app/controllers/alchemy/json_api/base_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module Alchemy
module JsonApi
class BaseController < ::ApplicationController
include Alchemy::ControllerActions
include Alchemy::AbilityHelper
include JSONAPI::Fetching
include JSONAPI::Errors
include JSONAPI::Filtering
Expand Down
9 changes: 7 additions & 2 deletions app/controllers/alchemy/json_api/pages_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,14 @@ def page_scope
end

def base_page_scope
::Alchemy::Page.
# cancancan is not able to merge our complex AR scopes for logged in users
if can?(:edit_content, Page)
pages = Page.all
else
pages = Page.accessible_by(current_ability, :index)
end
pages.
with_language(Language.current).
published.
preload(language: {nodes: [:parent, :page]}, all_elements: [:parent_element, :nested_elements, { contents: { essence: :ingredient_association } }])
end

Expand Down
55 changes: 49 additions & 6 deletions spec/requests/alchemy/json_api/layout_pages_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
require "rails_helper"
require "alchemy/test_support/factories/page_factory"
require "alchemy/test_support/factories/element_factory"
require "alchemy/devise/test_support/factories"

RSpec.describe "Alchemy::JsonApi::LayoutPagesController", type: :request do
let(:page) do
Expand Down Expand Up @@ -53,6 +54,30 @@
expect(response).to have_http_status(404)
end
end

context "when requesting an unpublished layout page" do
let(:page) { FactoryBot.create(:alchemy_page, :layoutpage) }

context "as anonymous user" do
it "returns a 404" do
get alchemy_json_api.layout_page_path(page.urlname)
expect(response).to have_http_status(404)
end
end

context "as admin" do
before do
allow_any_instance_of(ApplicationController).to receive(:current_user) do
FactoryBot.create(:alchemy_admin_user)
end
end

it "finds the page" do
get alchemy_json_api.layout_page_path(page.urlname)
expect(response).to have_http_status(200)
end
end
end
end

describe "GET /alchemy/json_api/layout_pages" do
Expand All @@ -61,12 +86,30 @@
let!(:non_public_layout_page) { FactoryBot.create(:alchemy_page, :layoutpage) }
let!(:public_page) { FactoryBot.create(:alchemy_page, :public) }

it "returns only public layout pages" do
get alchemy_json_api.layout_pages_path
document = JSON.parse(response.body)
expect(document["data"]).to include(have_id(layoutpage.id.to_s))
expect(document["data"]).not_to include(have_id(non_public_layout_page.id.to_s))
expect(document["data"]).not_to include(have_id(public_page.id.to_s))
context "as anonymous user" do
it "returns only public layout pages" do
get alchemy_json_api.layout_pages_path
document = JSON.parse(response.body)
expect(document["data"]).to include(have_id(layoutpage.id.to_s))
expect(document["data"]).not_to include(have_id(non_public_layout_page.id.to_s))
expect(document["data"]).not_to include(have_id(public_page.id.to_s))
end
end

context "as admin user" do
before do
allow_any_instance_of(ApplicationController).to receive(:current_user) do
FactoryBot.create(:alchemy_admin_user)
end
end

it "returns all layout pages" do
get alchemy_json_api.layout_pages_path
document = JSON.parse(response.body)
expect(document["data"]).to include(have_id(layoutpage.id.to_s))
expect(document["data"]).to include(have_id(non_public_layout_page.id.to_s))
expect(document["data"]).not_to include(have_id(public_page.id.to_s))
end
end
end

Expand Down
55 changes: 49 additions & 6 deletions spec/requests/alchemy/json_api/pages_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
require "rails_helper"
require "alchemy/test_support/factories/page_factory"
require "alchemy/test_support/factories/element_factory"
require "alchemy/devise/test_support/factories"

RSpec.describe "Alchemy::JsonApi::Pages", type: :request do
let(:page) do
Expand Down Expand Up @@ -71,6 +72,30 @@
expect(response).to have_http_status(404)
end
end

context "when requesting an unpublished page" do
let(:page) { FactoryBot.create(:alchemy_page) }

context "as anonymous user" do
it "returns a 404" do
get alchemy_json_api.page_path(page.urlname)
expect(response).to have_http_status(404)
end
end

context "as admin" do
before do
allow_any_instance_of(ApplicationController).to receive(:current_user) do
FactoryBot.create(:alchemy_admin_user)
end
end

it "finds the page" do
get alchemy_json_api.page_path(page.urlname)
expect(response).to have_http_status(200)
end
end
end
end

describe "GET /alchemy/json_api/pages" do
Expand All @@ -79,12 +104,30 @@
let!(:non_public_page) { FactoryBot.create(:alchemy_page) }
let!(:public_page) { FactoryBot.create(:alchemy_page, :public) }

it "returns public content pages only" do
get alchemy_json_api.pages_path
document = JSON.parse(response.body)
expect(document["data"]).not_to include(have_id(layoutpage.id.to_s))
expect(document["data"]).not_to include(have_id(non_public_page.id.to_s))
expect(document["data"]).to include(have_id(public_page.id.to_s))
context "as anonymous user" do
it "returns public content pages only" do
get alchemy_json_api.pages_path
document = JSON.parse(response.body)
expect(document["data"]).not_to include(have_id(layoutpage.id.to_s))
expect(document["data"]).not_to include(have_id(non_public_page.id.to_s))
expect(document["data"]).to include(have_id(public_page.id.to_s))
end
end

context "as admin user" do
before do
allow_any_instance_of(ApplicationController).to receive(:current_user) do
FactoryBot.create(:alchemy_admin_user)
end
end

it "returns all content pages" do
get alchemy_json_api.pages_path
document = JSON.parse(response.body)
expect(document["data"]).not_to include(have_id(layoutpage.id.to_s))
expect(document["data"]).to include(have_id(non_public_page.id.to_s))
expect(document["data"]).to include(have_id(public_page.id.to_s))
end
end
end

Expand Down

0 comments on commit b9ac752

Please sign in to comment.