Question

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?

Was it helpful?

Solution

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).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top