Skip to content

Commit

Permalink
Merge pull request #2370 from alphagov/allow-publishing-managers-to-m…
Browse files Browse the repository at this point in the history
…anage-their-apps

Allow Publishing Managers to manage their apps
  • Loading branch information
chrisroos authored Sep 28, 2023
2 parents 5c18e4f + 036a2ee commit 243f9eb
Show file tree
Hide file tree
Showing 13 changed files with 258 additions and 166 deletions.
4 changes: 2 additions & 2 deletions app/controllers/account/applications_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ class Account::ApplicationsController < ApplicationController
before_action :authenticate_user!

def show
authorize :account_applications
authorize [:account, Doorkeeper::Application]

redirect_to account_applications_path
end

def index
authorize :account_applications
authorize [:account, Doorkeeper::Application]

@applications_with_signin = Doorkeeper::Application.can_signin(current_user)
@applications_without_signin = Doorkeeper::Application.not_retired.without_signin_permission_for(current_user)
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/account/permissions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class Account::PermissionsController < ApplicationController
def index
@application = Doorkeeper::Application.not_retired.find(params[:application_id])

authorize current_user, :view_permissions?
authorize [:account, @application], :view_permissions?

@permissions = permissions_for(@application).sort_by { |permission| current_user.has_permission?(permission) ? 0 : 1 }
end
Expand Down
6 changes: 3 additions & 3 deletions app/controllers/account/signin_permissions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class Account::SigninPermissionsController < ApplicationController
before_action :authenticate_user!

def create
authorize current_user, :grant_signin_permission?
authorize [:account, Doorkeeper::Application], :grant_signin_permission?

application = Doorkeeper::Application.not_retired.find(params[:application_id])

Expand All @@ -17,13 +17,13 @@ def create
def delete
@application = Doorkeeper::Application.not_retired.find(params[:application_id])

authorize current_user, :remove_signin_permission?
authorize [:account, @application], :remove_signin_permission?
end

def destroy
application = Doorkeeper::Application.not_retired.find(params[:application_id])

authorize current_user, :remove_signin_permission?
authorize [:account, application], :remove_signin_permission?

params = { supported_permission_ids: current_user.supported_permissions.map(&:id) - [application.signin_permission.id] }
UserUpdate.new(current_user, params, current_user, user_ip_address).call
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def api_user_via_token_has_signin_permission_on_app?

def user_not_authorized(_exception)
flash[:alert] = "You do not have permission to perform this action."
redirect_to root_path
redirect_back_or_to root_path
end

def notify_bad_request(_exception)
Expand Down
20 changes: 20 additions & 0 deletions app/policies/account/application_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
class Account::ApplicationPolicy < BasePolicy
def index?
current_user.govuk_admin? || current_user.publishing_manager?
end

alias_method :show?, :index?
alias_method :view_permissions?, :index?

def grant_signin_permission?
current_user.govuk_admin?
end

def remove_signin_permission?
current_user.has_access_to?(record) &&
(
current_user.govuk_admin? ||
current_user.publishing_manager? && record.signin_permission.delegatable?
)
end
end
7 changes: 0 additions & 7 deletions app/policies/account_applications_policy.rb

This file was deleted.

6 changes: 0 additions & 6 deletions app/policies/user_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,6 @@ def edit?
alias_method :resend?, :edit?
alias_method :event_logs?, :edit?

def grant_signin_permission?
current_user.govuk_admin?
end
alias_method :remove_signin_permission?, :grant_signin_permission?
alias_method :view_permissions?, :grant_signin_permission?

def edit_email_or_password?
allow_self_only
end
Expand Down
22 changes: 13 additions & 9 deletions app/views/account/applications/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,17 @@
<td class="govuk-table__cell"><%= application.name %></td>
<td class="govuk-table__cell"><%= application.description %></td>
<td class="govuk-table__cell govuk-!-text-align-right">
<%= link_to account_application_permissions_path(application) do %>
<%= link_to account_application_permissions_path(application), class: "govuk-link" do %>
View permissions<span class="govuk-visually-hidden"> for <%= application.name %></span>
<% end %>
</td>
<td class="govuk-table__cell govuk-!-text-align-right">
<%= link_to delete_account_application_signin_permission_path(application),
class: "govuk-button govuk-button--warning govuk-!-margin-0",
data: { module: "govuk-button" } do %>
Remove access<span class="govuk-visually-hidden"> to <%= application.name %></span>
<% if policy([:account, application]).remove_signin_permission? %>
<%= link_to delete_account_application_signin_permission_path(application),
class: "govuk-button govuk-button--warning govuk-!-margin-0",
data: { module: "govuk-button" } do %>
Remove access<span class="govuk-visually-hidden"> to <%= application.name %></span>
<% end %>
<% end %>
</td>
</tr>
Expand All @@ -63,10 +65,12 @@
<td class="govuk-table__cell"><%= application.name %></td>
<td class="govuk-table__cell"><%= application.description %></td>
<td class="govuk-table__cell govuk-!-text-align-right">
<%= button_to account_application_signin_permission_path(application),
class: "govuk-button govuk-!-margin-0",
data: { module: "govuk-button" } do %>
Grant access<span class="govuk-visually-hidden"> to <%= application.name %></span>
<% if policy([:account, Doorkeeper::Application]).grant_signin_permission? %>
<%= button_to account_application_signin_permission_path(application),
class: "govuk-button govuk-!-margin-0",
data: { module: "govuk-button" } do %>
Grant access<span class="govuk-visually-hidden"> to <%= application.name %></span>
<% end %>
<% end %>
</td>
</tr>
Expand Down
2 changes: 1 addition & 1 deletion app/views/account/permissions/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<table class="govuk-table">
<thead class="govuk-table__head">
<tr class="govuk-table__row">
<th scope="col" class="govuk-table__header">Name</th>
<th scope="col" class="govuk-table__header govuk-!-width-three-quarters">Name</th>
<th scope="col" class="govuk-table__header">Has this permission?</th>
</tr>
</thead>
Expand Down
27 changes: 27 additions & 0 deletions test/controllers/account/applications_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,31 @@ class Account::ApplicationsControllerTest < ActionController::TestCase
assert_redirected_to "/account/applications"
end
end

context "#index" do
context "logged in as a publishing manager" do
should "not display the button to grant access to an application" do
application = create(:application, name: "app-name")
sign_in create(:organisation_admin_user)

get :index

assert_select "tr td", text: "app-name"
assert_select "form[action='#{account_application_signin_permission_path(application)}']", count: 0
end

should "not display the button to remove access to an application" do
application = create(:application, name: "app-name")
application.signin_permission.update!(delegatable: false)
user = create(:organisation_admin_user, with_signin_permissions_for: [application])

sign_in user

get :index

assert_select "tr td", text: "app-name"
assert_select "a[href='#{delete_account_application_signin_permission_path(application)}']", count: 0
end
end
end
end
190 changes: 190 additions & 0 deletions test/policies/account/application_policy_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
require "test_helper"
require "support/policy_helpers"

class Account::ApplicationPolicyTest < ActiveSupport::TestCase
include PolicyHelpers

context "accessing index?" do
%i[superadmin admin super_organisation_admin organisation_admin].each do |user_role|
context "for #{user_role} users" do
setup do
@current_user = FactoryBot.build(:"#{user_role}_user")
end

should "be permitted" do
assert permit?(@current_user, nil, :index)
end
end
end

%i[normal].each do |user_role|
context "for #{user_role} users" do
setup do
@current_user = FactoryBot.build(:"#{user_role}_user")
end

should "be forbidden" do
assert forbid?(@current_user, nil, :index)
end
end
end
end

context "show?" do
%i[superadmin admin super_organisation_admin organisation_admin].each do |user_role|
context "for #{user_role} users" do
setup do
@current_user = build(:"#{user_role}_user")
end

should "be permitted" do
assert permit?(@current_user, nil, :show)
end
end
end

%i[normal].each do |user_role|
context "for #{user_role} users" do
setup do
@current_user = build(:"#{user_role}_user")
end

should "be forbidden" do
assert forbid?(@current_user, nil, :show)
end
end
end
end

context "#grant_signin_permission?" do
%i[superadmin admin].each do |user_role|
context "for #{user_role} users" do
setup do
@current_user = build(:"#{user_role}_user")
end

should "be permitted" do
assert permit?(@current_user, nil, :grant_signin_permission)
end
end
end

%i[super_organisation_admin organisation_admin normal].each do |user_role|
context "for #{user_role} users" do
setup do
@current_user = build(:"#{user_role}_user")
end

should "be forbidden" do
assert forbid?(@current_user, nil, :grant_signin_permission)
end
end
end
end

context "#remove_signin_permission?" do
%i[superadmin admin].each do |user_role|
context "for #{user_role} users" do
setup do
@current_user = create(:"#{user_role}_user")
@application = create(:application)
end

context "when the user has signin permission for the app" do
setup do
@current_user.grant_application_signin_permission(@application)
end

should "be permitted" do
assert permit?(@current_user, @application, :remove_signin_permission)
end
end

context "when the user does not have the signin permission for the app" do
should "be forbidden" do
assert forbid?(@current_user, @application, :remove_signin_permission)
end
end
end
end

%i[super_organisation_admin organisation_admin].each do |user_role|
context "for #{user_role} users" do
setup do
@current_user = create(:"#{user_role}_user")
@application = create(:application)
end

context "when the user has signin permission for the app" do
setup do
@current_user.grant_application_signin_permission(@application)
end

context "and the application has delegatable permissions" do
setup do
@application.signin_permission.update!(delegatable: true)
end

should "be permitted" do
assert permit?(@current_user, @application, :remove_signin_permission)
end
end

context "and the application does not have delegatable permissions" do
setup do
@application.signin_permission.update!(delegatable: false)
end

should "not be permitted" do
assert forbid?(@current_user, @application, :remove_signin_permission)
end
end
end

context "when the user does not have the signin permission for the app" do
should "be forbidden" do
assert forbid?(@current_user, @application, :remove_signin_permission)
end
end
end
end

%i[normal].each do |user_role|
context "for #{user_role} users" do
setup do
@current_user = build(:"#{user_role}_user")
end

should "be forbidden" do
assert forbid?(@current_user, nil, :remove_signin_permission)
end
end
end
end

context "#view_permissions?" do
%i[superadmin admin super_organisation_admin organisation_admin].each do |user_role|
context "for #{user_role} users" do
setup do
@current_user = build(:"#{user_role}_user")
end

should "be permitted" do
assert permit?(@current_user, nil, :view_permissions)
end
end
end

%i[normal].each do |user_role|
context "for #{user_role} users" do
setup do
@current_user = build(:"#{user_role}_user")
end

should "be forbidden" do
assert forbid?(@current_user, nil, :view_permissions)
end
end
end
end
end
Loading

0 comments on commit 243f9eb

Please sign in to comment.