diff --git a/app/controllers/plans_controller.rb b/app/controllers/plans_controller.rb index 06373d9..bd0559b 100644 --- a/app/controllers/plans_controller.rb +++ b/app/controllers/plans_controller.rb @@ -7,6 +7,10 @@ def index authorize Plan @plans = current_user.active_plans + @organisationally_or_publicly_visible_by_org = + current_user.org_id.present? ? + Plan.includes(:roles).organisationally_or_publicly_visible_by_org(current_user.org_id).to_a.select{ |p| !p.any_role?(current_user) } : + [] end # GET /plans/new diff --git a/app/controllers/public_pages_controller.rb b/app/controllers/public_pages_controller.rb index de6a531..bf33360 100644 --- a/app/controllers/public_pages_controller.rb +++ b/app/controllers/public_pages_controller.rb @@ -52,7 +52,7 @@ def plan_export @plan = Plan.find(params[:id]) # covers authorization for this action. Pundit dosent support passing objects into scoped policies - raise Pundit::NotAuthorizedError unless PublicPagePolicy.new( @plan).plan_export? + raise Pundit::NotAuthorizedError unless PublicPagePolicy.new(@plan, current_user).plan_organisationally_exportable? || PublicPagePolicy.new(@plan).plan_export? skip_authorization # This creates exported_plans with no user. # Note for reviewers, The ExportedPlan model actually serves no purpose, except diff --git a/app/models/plan.rb b/app/models/plan.rb index 84f2a76..989d63c 100644 --- a/app/models/plan.rb +++ b/app/models/plan.rb @@ -55,6 +55,11 @@ # Note that in ActiveRecord::Enum the mappings are exposed through a class method with the pluralized attribute name (e.g visibilities rather than visibility) scope :publicly_visible, -> { where(:visibility => visibilities[:publicly_visible]).order(:title => :asc) } + # Retrieves any plan organisationally or publicly visible for a given org id + scope :organisationally_or_publicly_visible_by_org, -> (org_id) { + joins(:template).where( + visibility: [visibilities[:organisationally_visible], visibilities[:publicly_visible]], + "templates.org_id": org_id).order(:title => :asc) } ## # Settings for the template has_settings :export, class_name: 'Settings::Template' do |s| @@ -305,6 +310,16 @@ end ## + # determines whether or not the specified user has any rol on the plan + # + # @param user_id [Integer] the id for the user + # @return [Boolean] true if the user has any rol + def any_role?(user) + user_id = user.id if user.is_a?(User) + !self.roles.index{ |rol| rol.user_id == user_id }.nil? + end + + ## # defines and returns the status of the plan # status consists of a hash of the num_questions, num_answers, sections, questions, and spaced used. # For each section, it contains the id's of each of the questions diff --git a/app/policies/public_page_policy.rb b/app/policies/public_page_policy.rb index e4b237b..4721351 100644 --- a/app/policies/public_page_policy.rb +++ b/app/policies/public_page_policy.rb @@ -1,8 +1,8 @@ class PublicPagePolicy < ApplicationPolicy - def initialize( object) - # no requirement for users to be signed in here + def initialize(object, object2 = nil) @object = object + @object2 = object2 end def plan_index? @@ -21,4 +21,12 @@ @object.publicly_visible? end + def plan_organisationally_exportable? + plan = @object + user = @object2 + if plan.is_a?(Plan) && user.is_a?(User) + return plan.publicly_visible? || (plan.organisationally_visible? && plan.template.org_id == user.org_id) + end + return false; + end end diff --git a/app/views/plans/_publicly_visible_org.html.erb b/app/views/plans/_publicly_visible_org.html.erb new file mode 100644 index 0000000..6d83d5d --- /dev/null +++ b/app/views/plans/_publicly_visible_org.html.erb @@ -0,0 +1,46 @@ +<% if current_user.org_id.present? %> +
| + <%= render(partial: "shared/table_filter", + locals: { placeholder: _('Filter plans')}) %> + | +||||
|---|---|---|---|---|
| <%= _('Project Title') %> | +<%= _('Template') %> | +<%= _('Owner') %> | +<%= _('Updated') %> | +<%= _('Download') %> | +
| <%= link_to "#{plan.title.length > 40 ? "#{plan.title[0..39]} ..." : plan.title}", plan_path(plan) %> | +<%= plan.template.title %> | +<%= plan.owner.present? ? plan.owner.name : _('Unknown') %> | +<%= l(plan.latest_update.to_date, formats: :short) %> | ++ <%= link_to _('PDF'), plan_export_path(plan, format: :pdf), target: '_blank' %> + | +