I am working on a plugin for Redmine and I created a method which sends two HTTP requests (using POST method) to attach a new file to a document.
The first request works well (see Webrick console below)
Started POST "/redmine/uploads.json?attachment_id=1&filename=testFile.txt" for <server_IP_address> at 2014-04-04 11:37:58 +0200
Processing by AttachmentsController#upload as JSON
Parameters: {"attachment_id"=>"1", "filename"=>"testFile.txt"}
Current user: <user> (id=3)
Saving attachment '/home/user/Redmine/redmine-2.4.2/files/2014/04/140404113759_testFile.txt' (72 bytes)
Rendered attachments/upload.api.rsb (1.2ms)
Completed 201 Created in 661.6ms (Views: 82.6ms | ActiveRecord: 15.6ms)
Then the second request is executed:
Started POST "/redmine/documents/150/add_attachment.xml" for <server_IP_address> at 2014-04-04 11:37:59 +0200
Processing by DocumentsController#add_attachment as XML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"<auth_token>", "attachments"=>{"1"=>{"filename"=>"testFile.txt", "description"=>"Dropbox blabla", "token"=>"<upToken>"}}, "commit"=>"Add", "id"=>"150"}
Current user: anonymous
Filter chain halted as :authorize rendered or redirected
Completed 401 Unauthorized in 132.6ms (ActiveRecord: 3.0ms)
I get this error because the Current user here is anonymous
(I think), I don't understand why, if I print a User.current
after the first request the user is still logged.
I created the first request using the net/http
library ant the second using RestClient
, here is my code:
uri = URI.parse("http://<server_IP_address>/redmine/uploads.json")
http = Net::HTTP.new(uri.host, uri.port)
file = File.new("/home/testFile.txt")
@csrfToken = session[:_csrf_token]
@apiKey = User.current.api_key
@request = Net::HTTP::Post.new(uri.path+"?attachment_id=1&filename=testFile.txt", initheader = {'Content-Type' => "application/octet-stream", 'X-CSRF-Token' => @csrfToken, 'X-Redmine-API-Key' => @apiKey})
@request.body = @file.read
@response = http.request(@request)
@upToken = ActiveSupport::JSON.decode(@response.body)['upload']['token']
@secondResponse = RestClient.post 'http://<server_IP_address>/redmine/documents/150/add_attachment.xml', {:multipart => true, :utf8 => "\u2713", :authenticity_token => @csrfToken, :attachments => { "1" => {:filename => "testFile.txt", :description => "Dropbox blabla", :token => @upToken}}, :commit => "Add"}, 'X-Redmine-API-Key' => @apiKey, 'X-CSRF-Token' => @csrfToken, 'Cookie' => cookies[:_redmine_session]
As you see I tried to set the Cookie
header with the data of my session but it doesn't work.
I tried to write the second request with the same library as the first one but I get the same error. Do you know why my user is not recognized? How can I change that?
I finally found why the user is set on anonymous
:
First, I discovered that by adding logger.info("some text and variables")
in the controller code these informations are going to be displayed in the <redmine_install_dir>/log/production.log>
file, this is pretty helpful.
In the Redmine ApplicationController
, a before_filter
is defined thus some methods are called before the execution of my second request. I took a look at these methods and one of them (find_current_user
) set the user to nil
then re-set the user according to some conditions, and I found out that none of these conditions are verified so the user stays nil
.
So it looks like the problem come from the Redmine API, my action
seems to be not authorized.
If somebody is interested in this, I can expand my answer by showing part of the Redmine code (althought you can see it on GitHub or somewhere else).