How to work correctly with the permissions in a plugin?

Added by Riewert Holtermann about 9 years ago

Hello,

I followed the tutorial for creating a redmine-plugin.
Everything worked fine till I came to the point of changing the permissions.
When everybody was able to read the votes and to make a vote for the polls, no
errors occured.
Then I changed the permissions, so that they where enabled or disabled in the
UI of Redmine. I tried to chage the permission for voting the polls in the same
way I did it for the indexing.

This is my polls_controller.rb:

class PollsController < ApplicationController
unloadable

before_filter :find_project, :authorize, :only => [:vote, :index]
def index
@polls = Poll.find(:all) # @project.polls
end
def vote
poll = Poll.find(params[:id])
poll.vote(params[:answer])
if poll.save
flash[:notice] = 'Vote saved.'
redirect_to :action => 'index'
end
end
private
def find_project
  # @project variable must be set before calling the authorize filter
@project = Project.find(params[:project_id])
end
end

May be the error is quite easy to resolve, but I don't see it.

I get this error for voting:

ActiveRecord::RecordNotFound in PollsController#vote

Couldn't find Project without an ID

Regards.
Riewert

My system:
OS Win7
Redmine 1.0.1 running on Mongrel/Apache

Replies (6)

RE: How to work correctly with the permissions in a plugin? - Added by Ash Shelton about 9 years ago

I had the exact same thing, but as I have to learn this stuff to help my company make a plugin I spent some time trying to figure out why.

To get it working with permissions I had to make the following changes:

polls_controller.rb

class PollsController < ApplicationController
    unloadable

    before_filter :find_project, :authorize, :only => :index
    before_filter :find_project, :authorize, :only => :vote

    def index
        @polls = Poll.find(:all)
    end

    def vote
        poll = Poll.find(params[:id])
        poll.vote(params[:answer])
        if poll.save
            flash[:notice] = 'Vote saved.'
            redirect_to :action => 'index', :project_id => Project.find(params[:project_id]) 
        end
    end

    def find_project
        # @project variable must be set before calling the authorize filter
        @project = Project.find(params[:project_id])
    end
end

index.html.erb

<h2>Polls</h2>

<% content_for :header_tags do %>
    <%= stylesheet_link_tag 'voting', :plugin => 'redmine_polls' %>
<% end %>

<% @polls.each do |poll| %>
  <p>
  <%= poll[:question] %>?
  <%= link_to 'Yes', {:action => 'vote', :id => poll[:id], :answer => 'yes', :project_id => Project.find(params[:project_id])}, :method => :post %> (<%= poll[:yes] %>) /
  <%= link_to 'No', {:action => 'vote', :id => poll[:id], :answer => 'no', :project_id => Project.find(params[:project_id])}, :method => :post %> (<%= poll[:no] %>)
  </p>
<% end %>

Im not sure if they're the most efficient because I assume the project ID was stored as a variable on the index page and I could have simply passed it to the voting page, however I'm so fresh to this that I'm not sure how to do that yet but calling 'find' for both the yes/no links on index.html.erb works fine.

RE: How to work correctly with the permissions in a plugin? - Added by Riewert Holtermann almost 9 years ago

Thank you for your answer.

This solves this problem.

Now I have the nearly same problem in an other plugin.
Did you find out, where the project_id is stored and how you can get access to it?

Can anyone please help me, how I can get access of der current project_id from
inside of a plugin?

Best Regards

RE: How to work correctly with the permissions in a plugin? - Added by Riewert Holtermann almost 9 years ago

I think I need some general help.

In the first view of my plugin, everything works fine, by pressing a button I link to another page and I send the ID into the next view, again everything works fine, the second view is displayed.
This second view is a form. I fill out the form and want to send the data into the database. I have been doing this in an other program before and in this program it works. I press a button, I created via a submit_tag, call the action create ang get the error: »Couldn't get Project without an ID«
I don't know, what to do, I hove someone can help me PLEASE.

Best Regards
Riewert

RE: How to work correctly with the permissions in a plugin? - Added by Felix Schäfer almost 9 years ago

Well, it seems you're doing something that tries to find a project, but you don't provide a project ID so it can't find one.

You'll have to post at least the code from your controller, just saying "it makes funny stuff" is not very useful :-)

RE: How to work correctly with the permissions in a plugin? - Added by Miguel Akira over 8 years ago

I'm kinda new to rails and very new to Redmine, and was stumbling with the same problem - trying to submit a "Report" form that belongs to a Project. Everything worked fine, except when I tried to submit. Searching around, I found this solution (I don't know if it's good, but it worked here):

class RelatoriosController < ApplicationController

  def create
    @project = Project.find(params[:project_id])
    @relatorio = Relatorio.new(params[:relatorio])
    @relatorio.project_id = @project.id

    respond_to do |format|
      if @relatorio.save
        flash[:notice] = 'Relatorio was successfully created.'
        format.html { redirect_to :controller => 'relatorios', :action => 'index', :project_id => Project.find(params[:project_id]) }
    format.xml  { render :xml => @relatorio, :status => :created, :location => @relatorio }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @relatorio.errors, :status => :unprocessable_entity }
      end
    end
  end

and the view:

<h1>New relatorio</h1>

<% form_for :relatorio, @relatorio, :url => { :controller => 'relatorios', :action => 'create', :project_id =>@project }   do |f| %>
  <%= f.error_messages %>
    <legend> Adicionar detalhes </legend>

    <label for = "title"> Titulo: </label> <br />
    <%= f.text_field :title, :size=>'35' %> <br />

    <label for = "body"> Corpo: </label> <br />
    <%= f.text_area :body, :cols=>'80', :rows=>'20' %> <br />

    <p>

    <%= f.submit 'Create' %>
  </p>
<% end %>

<%= link_to 'Back', :controller => 'relatorios', :action => 'index',:project_id => Project.find(params[:project_id]) %>

That's working for me!

RE: How to work correctly with the permissions in a plugin? - Added by Thomas Kohler over 8 years ago

Hello, I have had the same problem.
In my opinion the main bug is the lack of project information inside the index.html.erb file. I have fixed this issue with ,:project_id => @project. Now it is more clear that the action "index" need also this information. Therefore I have also extended the redirect line inside the polls_controller.rb with , :project_id => @project. Last but not least the ,:only => :index at filter line has to be commented out or deleted. Because simple adding this line: before_filter :find_project, :authorize, :only => :vote don't work good enough for me.

Thanks for the hints above. This have also fixed the bug in a similar way.
Good luck, Thomas

(1-6/6)