Skip to content

Commit

Permalink
Update access to services
Browse files Browse the repository at this point in the history
- All users can see services, but only their own
- GDS Editors can see all services, and update
  the organisation_slugs for a service using the
  new Update Owner form

Co-authored-by: Ramya Vidapanakal <[email protected]>
  • Loading branch information
KludgeKML and sairamya93 committed Aug 12, 2024
1 parent 4105168 commit 2534848
Show file tree
Hide file tree
Showing 9 changed files with 276 additions and 9 deletions.
33 changes: 31 additions & 2 deletions app/controllers/services_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ class ServicesController < ApplicationController
include LinkImporterUtils

before_action :set_service, except: :index
before_action :check_permissions, except: :index

helper_method :org_name_for_current_user

def index
@services = Service.enabled.order(broken_link_count: :desc)
raise "Missing Data" if @services.empty?
@services = services_for_user(current_user).enabled.order(broken_link_count: :desc)
# raise "Missing Data" if @services.empty?

@breadcrumbs = index_breadcrumbs
end
Expand All @@ -18,6 +21,22 @@ def show
@breadcrumbs = service_breadcrumbs(@service)
end

def update_owner_form
raise GDS::SSO::PermissionDeniedError, "You do not have permission to view this page" unless gds_editor?

@breadcrumbs = service_breadcrumbs(@service) + [{ title: "Update Owner", url: update_owner_form_service_path(@service) }]
end

def update_owner
Rails.logger.info(params)

raise GDS::SSO::PermissionDeniedError, "You do not have permission to view this page" unless gds_editor?

@service.update!(organisation_slugs: params["service"]["organisation_slugs"].split(" "))

redirect_to service_path(@service, filter: "broken_links")
end

def download_links_form
@breadcrumbs = service_breadcrumbs(@service) + [{ title: "Download Links", url: download_links_form_service_path(@service) }]
end
Expand All @@ -40,10 +59,20 @@ def upload_links_csv

private

def services_for_user(user)
return Service.all if gds_editor?

Service.where(":organisation_slugs = ANY(organisation_slugs)", organisation_slugs: user.organisation_slug)
end

def set_service
@service = Service.find_by!(slug: params[:service_slug])
end

def check_permissions
raise GDS::SSO::PermissionDeniedError, "You do not have permission to view this page" unless permission_for_service?(@service)
end

def links_for_service
@links_for_service ||= filtered_links(@service.links)
.includes(%i[interaction local_authority service_interaction])
Expand Down
1 change: 1 addition & 0 deletions app/presenters/service_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ def summary_list(view_context)

summary_items = [
{ field: "Local Government Service List (LGSL) Code", value: lgsl_code },
{ field: "Owning Departments", value: organisation_slugs.join(", ") },
{ field: "Page title(s) on GOV.UK", value: govuk_links.compact.any? ? govuk_links.compact.join("</br>").html_safe : "Not used on GOV.UK" },
]

Expand Down
5 changes: 3 additions & 2 deletions app/views/services/index.html.erb
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
<% content_for :page_title, "Services" %>
<% title = gds_editor? ? "Services" : "Services for #{org_name_for_current_user}" %>
<% content_for :page_title, title %>
<% breadcrumb :services %>
<%= render "govuk_publishing_components/components/heading", {
text: "Services (#{@services.count})",
text: "#{title} (#{@services.count})",
heading_level: 1,
font_size: "l",
margin_bottom: 5,
Expand Down
13 changes: 8 additions & 5 deletions app/views/services/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@
<aside class="app-side__wrapper">
<div class="app-side">
<div class="app-side__actions">
<%
items = []
items << link_to("Update Owner", update_owner_form_service_path(@service), class: "govuk-link") if gds_editor?
items << link_to("Download Links", download_links_form_service_path(@service), class: "govuk-link")
items << link_to("Upload Links", upload_links_form_service_path(@service), class: "govuk-link")
items << link_to(@filter_var == "broken_links" ? "Show only broken links" : "Show all links", service_path(@service.slug, filter: @filter_var), class: "govuk-link")
%>
<%= render "govuk_publishing_components/components/list", {
items: [
link_to("Download Links", download_links_form_service_path(@service), class: "govuk-link"),
link_to("Upload Links", upload_links_form_service_path(@service), class: "govuk-link"),
link_to(@filter_var == "broken_links" ? "Show only broken links" : "Show all links", service_path(@service.slug, filter: @filter_var), class: "govuk-link"),
],
items:,
margin_bottom: 0,
} %>
</div>
Expand Down
23 changes: 23 additions & 0 deletions app/views/services/update_owner_form.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<% content_for :page_title, "Update Owner" %>
<%= render "govuk_publishing_components/components/heading", {
text: "Update Owner",
heading_level: 1,
font_size: "l",
margin_bottom: 5,
} %>
<%= form_for(@service, url: update_owner_service_path(@service)) do %>
<%= render "govuk_publishing_components/components/input", {
label: { text: "Organisation Slugs" },
hint: "For multiple owning organisations, list slugs separated by spaces",
name: "service[organisation_slugs]",
value: @service&.organisation_slugs,
} %>
<%= render "govuk_publishing_components/components/button", { text: "Submit" } %>
<%= render "govuk_publishing_components/components/button", {
text: "Cancel",
secondary_quiet: true,
href: service_path(@service, filter: "broken_links"),
} %>
<% end %>
2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
post "download_links_csv"
get "upload_links_form"
post "upload_links_csv"
get "update-owner-form"
patch "update-owner"
end
end

Expand Down
72 changes: 72 additions & 0 deletions spec/requests/services_page_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
RSpec.describe "Services page" do
let(:owning_department) { "department-of-aardvarks" }
let!(:service) { create(:service, label: "Aardvark Wardens", organisation_slugs: [owning_department]) }

describe "GET /services/:service_slug" do
it_behaves_like "it is forbidden to non-owners", "/services/aardvark-wardens", "department-of-aardvarks"
end

describe "GET /services/:service_slug/download_links_form" do
it_behaves_like "it is forbidden to non-owners", "/services/aardvark-wardens/download_links_form", "department-of-aardvarks"
end

describe "GET /services/:service_slug/upload_links_form" do
it_behaves_like "it is forbidden to non-owners", "/services/aardvark-wardens/upload_links_form", "department-of-aardvarks"
end

describe "GET /services/:service_slug/update-owner-form" do
context "as a GDS Editor" do
before { login_as_gds_editor }

it "returns 200 OK" do
get "/services/aardvark-wardens/update-owner-form"

expect(response).to have_http_status(:ok)
end
end

context "as a department user (even) from the owning department" do
before { login_as_department_user(organisation_slug: owning_department) }

it "returns 403 Forbidden" do
get "/services/aardvark-wardens/update-owner-form"

expect(response).to have_http_status(:forbidden)
end
end
end

describe "PATCH /services/:service_slug/update-owner" do
context "as a GDS Editor" do
before { login_as_gds_editor }

it "returns 200 OK" do
patch "/services/aardvark-wardens/update-owner", params: { service: { organisation_slugs: "new-owner" } }

expect(response).to redirect_to("/services/aardvark-wardens?filter=broken_links")
end

it "updates the organisation slugs" do
patch "/services/aardvark-wardens/update-owner", params: { service: { organisation_slugs: "new-owner" } }

expect(service.reload.organisation_slugs).to eq(%w[new-owner])
end
end

context "as a department user (even) from the owning department" do
before { login_as_department_user(organisation_slug: owning_department) }

it "returns 403 Forbidden" do
patch "/services/aardvark-wardens/update-owner", params: { service: { organisation_slugs: "new-owner" } }

expect(response).to have_http_status(:forbidden)
end

it "does not update the organisation slugs" do
patch "/services/aardvark-wardens/update-owner", params: { service: { organisation_slugs: "new-owner" } }

expect(service.reload.organisation_slugs).to eq([owning_department])
end
end
end
end
59 changes: 59 additions & 0 deletions spec/system/service_page_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
RSpec.describe "Service page" do
before do
create(:service, label: "Aardvark Wardens", organisation_slugs: %w[department-of-aardvarks])
end

describe "Visiting the page" do
context "as an owning department user" do
before { login_as_department_user(organisation_slug: "department-of-aardvarks") }

it "does not show the Update Owner link" do
visit "/services/aardvark-wardens"

expect(page).not_to have_content("Update Owner")
end
end

context "as a GDS Editor" do
before { login_as_gds_editor }

it "shows the Update Owner link" do
visit "/services/aardvark-wardens"

expect(page).to have_content("Update Owner")
end
end
end

describe "Updating the owner" do
before { login_as_gds_editor }

it "allows us to update the owner" do
visit "/services/aardvark-wardens"

expect(page).to have_content("department-of-aardvarks")
expect(page).not_to have_content("government-digital-service")

click_on "Update Owner"
fill_in "Organisation Slug", with: "government-digital-service"
click_on "Submit"

expect(page).not_to have_content("department-of-aardvarks")
expect(page).to have_content("government-digital-service")
end

it "allows us to cancel updating the owner" do
visit "/services/aardvark-wardens"

expect(page).to have_content("department-of-aardvarks")
expect(page).not_to have_content("government-digital-service")

click_on "Update Owner"
fill_in "Organisation Slug", with: "government-digital-service"
click_on "Cancel"

expect(page).to have_content("department-of-aardvarks")
expect(page).not_to have_content("government-digital-service")
end
end
end
77 changes: 77 additions & 0 deletions spec/system/services_page_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
require "gds_api/test_helpers/organisations"

RSpec.describe "Services page" do
include GdsApi::TestHelpers::Organisations

before do
create(:service, label: "Aardvark Wardens", organisation_slugs: %w[department-of-aardvarks])
end

context "as a gds editor" do
before { login_as_gds_editor }

it "shows all the services" do
visit "/services"

expect(page).to have_content("Aardvark Wardens")
end

it "shows a generic title" do
visit "/services"

expect(page).to have_content("Services (1)")
end
end

context "as a department user" do
before do
stub_organisations_api_has_organisations_with_bodies([{ "title" => "Department of Randomness", "details" => { "slug" => "random-department" } }])
login_as_department_user
end

it "does not show Aardvark Wardens service" do
visit "/services"

expect(page).not_to have_content("Aardvark Wardens")
end

it "shows a department title" do
visit "/services"

expect(page).to have_content("Services for Department of Randomness (0)")
end

context "if the Organisations API fails" do
before do
stub_request(:get, "#{Plek.new.website_root}/api/organisations/random-department").to_raise(GdsApi::HTTPUnavailable)
end

it "shows a generic title" do
visit "/services"

expect(page).to have_content("Services for random-department (0)")
end
end
end

context "as a user from an owning department" do
before do
stub_organisations_api_has_organisations_with_bodies([{ "title" => "Department of Aardvarks", "details" => { "slug" => "department-of-aardvarks" } }])
login_as_department_user(organisation_slug: "department-of-aardvarks")
end

before { login_as_department_user(organisation_slug: "department-of-aardvarks") }

it "shows the related services only" do
visit "/services"

expect(page).to have_content("Aardvark Wardens")
end

it "shows a department title" do
visit "/services"

expect(page).to have_content("Services for Department of Aardvarks (1)")
end
end
end

0 comments on commit 2534848

Please sign in to comment.