DMPRoadmap / roadmap

DCC/UC3 collaboration for a data management planning tool
MIT License
102 stars 109 forks source link

Conflicting download plan rules lead to non workable downloads #3345

Open nicolasfranck opened 9 months ago

nicolasfranck commented 9 months ago

Please complete the following fields as applicable:

What version of the DMPRoadmap code are you running? (e.g. v2.2.0)

4.1.0

Expected behaviour:

When a plan download is listed somewhere as downloadable, it should be downloadable

Actual behaviour:

Some plans, on your "dashboard", that are only "organizational or publicly" visible, have a download link. But some of those links lead to this error:

Sep 26 15:01:52 dmponline 9bc6d88a2440[1233]: I, [2023-09-26T13:01:52.471769 #16]  INFO -- : [5dd0d329-62d8-4e70-a66d-4fb778576dca] Started GET "/plans/64841/export.pdf?export%5Bquestion_headings%5D=true" for 193.190.130.1 at 2023-09-26 13:01:52 +0000
Sep 26 15:01:52 dmponline 9bc6d88a2440[1233]: I, [2023-09-26T13:01:52.474673 #16]  INFO -- : [5dd0d329-62d8-4e70-a66d-4fb778576dca] Processing by PlanExportsController#show as PDF
Sep 26 15:01:52 dmponline 9bc6d88a2440[1233]: I, [2023-09-26T13:01:52.474766 #16]  INFO -- : [5dd0d329-62d8-4e70-a66d-4fb778576dca]   Parameters: {"export"=>{"question_headings"=>"true"}, "plan_id"=>"64841"}
Sep 26 15:01:52 dmponline 9bc6d88a2440[1233]: E, [2023-09-26T13:01:52.511655 #16] ERROR -- : [5dd0d329-62d8-4e70-a66d-4fb778576dca] You are not authorized to perform this action.
Sep 26 15:01:52 dmponline 9bc6d88a2440[1233]: I, [2023-09-26T13:01:52.512251 #16]  INFO -- : [5dd0d329-62d8-4e70-a66d-4fb778576dca] Completed 406 Not Acceptable in 37ms (ActiveRecord: 14.5ms | Allocations: 5859)
Sep 26 15:01:52 dmponline 9bc6d88a2440[1233]: F, [2023-09-26T13:01:52.513138 #16] FATAL -- : [5dd0d329-62d8-4e70-a66d-4fb778576dca]   
Sep 26 15:01:52 dmponline 9bc6d88a2440[1233]: [5dd0d329-62d8-4e70-a66d-4fb778576dca] ActionController::UnknownFormat (ActionController::UnknownFormat):
Sep 26 15:01:52 dmponline 9bc6d88a2440[1233]: [5dd0d329-62d8-4e70-a66d-4fb778576dca]   
Sep 26 15:01:52 dmponline 9bc6d88a2440[1233]: [5dd0d329-62d8-4e70-a66d-4fb778576dca] app/controllers/application_controller.rb:189:in `render_respond_to_format_with_error_message'
Sep 26 15:01:52 dmponline 9bc6d88a2440[1233]: [5dd0d329-62d8-4e70-a66d-4fb778576dca] app/controllers/application_controller.rb:37:in `user_not_authorized'
Sep 26 15:01:52 dmponline 9bc6d88a2440[1233]: I, [2023-09-26T13:01:52.572407 #16]  INFO -- : [f73e7576-4513-424b-9c2b-f3b5efecd6f9] Started GET "/favicon.ico" for 193.190.130.1 at 2023-09-26 13:01:52 +0000
Sep 26 15:01:52 dmponline 9bc6d88a2440[1233]: F, [2023-09-26T13:01:52.574447 #16] FATAL -- : [f73e7576-4513-424b-9c2b-f3b5efecd6f9]   
Sep 26 15:01:52 dmponline 9bc6d88a2440[1233]: [f73e7576-4513-424b-9c2b-f3b5efecd6f9] ActionController::RoutingError (No route matches [GET] "/favicon.ico"):
Sep 26 15:01:52 dmponline 9bc6d88a2440[1233]: [f73e7576-4513-424b-9c2b-f3b5efecd6f9]   

This happened to a plan with the following characteristics (example):

Steps to reproduce:

Notes and thoughts

# authorization
if privately_authorized? || publicly_authorized?
  skip_authorization
else
  raise Pundit::NotAuthorizedError
end

# format settings
if privately_authorized? && export_params[:form].present?
   # provide settings from form
else
  # set default settings
end  
aaronskiba commented 2 months ago
    # app/controllers/plan_exports_controller.rb
    if privately_authorized? && export_params[:form].present?
      skip_authorization
      @show_coversheet         = export_params[:project_details].present?
      @show_sections_questions = export_params[:question_headings].present?
      @show_unanswered         = export_params[:unanswered_questions].present?
      @show_custom_sections    = export_params[:custom_sections].present?
      @show_research_outputs   = export_params[:research_outputs].present?
      @public_plan             = false

    elsif publicly_authorized?
      skip_authorization
      @show_coversheet         = true
      @show_sections_questions = true
      @show_unanswered         = true
      @show_custom_sections    = true
      @show_research_outputs   = @plan.research_outputs&.any? || false
      @public_plan             = true

##################################################################

  def publicly_authorized?
    PublicPagePolicy.new(current_user, @plan).plan_organisationally_exportable? ||
      PublicPagePolicy.new(current_user, @plan).plan_export?
  end
  # app/policies/public_page_policy.rb
  def plan_export?
    @record.publicly_visible?
  end

  def plan_organisationally_exportable?
    if @record.is_a?(Plan) && @user.is_a?(User)
      return @record.publicly_visible? ||
             (@record.organisationally_visible? && @record.owner.present? &&
              @record.owner.org_id == @user.org_id)
    end

As @nicolasfranck pointed out, in the "Organization Plans section" of the /plans page, plans where plan.owner.org_id != current_user.org_id are listed. But for the elsif publicly_authorized? check to be true, @record.owner.org_id == @user.org_id must also be true. So we have a mismatch here. Either certain plans should not be listed in the first place, or else def plan_organisationally_exportable? must be updated to enable download of these organizational plans.

I'm also wondering about the following question posed by @nicolasfranck: "Normally the creator of the plan has the same organization as the organization of the plan. But according to this line, the organization of the plan itself can also be set when the primary research organization is set. Why should one do this? The primary research organization is only important for template selection, right? That is the only reason why this may happen, not?"