Nikage Nikage - 4 months ago 10
Ruby Question

Ruby on rails controller copy does not autorize user

Disclaimer: I'm completely new to ruby..

I've copied this controller with the name

timelog_estimates_controller.rb
, changed the class name to
TimelogEstimatesController
created different route but the page gives me "403 forbidden"

When I use the original TimelogController it works perfectly fine.
I suppose there is something I've missed.

Answer

Redmine uses declarative permissioning. When you created a new controller, it and its actions are missing from permissions definition and therefore inaccessible.

To fix that you need to include your new controller's relevant actions into permissions definitions. This is the location in lib/redmine.rb you probably need to modify. Copied here for clarity:

  map.project_module :time_tracking do |map|
    map.permission :log_time, {:timelog => [:new, :create]}, :require => :loggedin
    map.permission :view_time_entries, {:timelog => [:index, :report, :show]}, :read => true
    map.permission :edit_time_entries, {:timelog => [:edit, :update, :destroy, :bulk_edit, :bulk_update]}, :require => :member
    map.permission :edit_own_time_entries, {:timelog => [:edit, :update, :destroy,:bulk_edit, :bulk_update]}, :require => :loggedin
    map.permission :manage_project_activities, {:project_enumerations => [:update, :destroy]}, :require => :member
  end

You should add something like this inside this block:

    map.permission :view_time_estimates, {:timelog_estimates => [:index, :report, :show]}, :read => true
    map.permission :edit_time_estimates, {:timelog_estimates => [:edit, :update, :destroy, :bulk_edit, :bulk_update]}, :require => :member
    map.permission :edit_own_time_estimates, {:timelog_estimates => [:edit, :update, :destroy,:bulk_edit, :bulk_update]}, :require => :loggedin

The authorization works through this call in your controller:

before_filter :authorize_global, :only => [:new, :create, :index, :report]

If you follow authorize_global implementation, you will find this:

  # Authorize the user for the requested action
  def authorize(ctrl = params[:controller], action = params[:action], global = false)
    allowed = User.current.allowed_to?({:controller => ctrl, :action => action}, @project || @projects, :global => global)
    if allowed
      true
    else
      if @project && @project.archived?
        render_403 :message => :notice_not_authorized_archived_project
      else
        deny_access
      end
    end
  end

The render_403 line is the reason you're getting the error.