How fix put method erorr - put

i want to update users, but always get 404 (Cannot PUT /api/users). Calling api/users to router.put('/:id' , What am i missing? How do you solve users update thing?

The code 404 means that the API endpoint is not found.
Your users API is listening for /users/:id, and then that is attached under api/users.
This means that the actual path that Express is listening on is /api/users/users/:id.
Change the /users/:id to /:id and it should work.

Related

Is it safe to accept URL parameters for populating the `url_for` method?

I am using Ruby on Rails 4.1.1 and I am thinking to accept parameters (through URL query strings) that are passed directly to the url_for method, this way:
# URL in the browser
http://www.myapp.com?redirect_to[controller]=users&redirect_to[action]=show&redirect_to[id]=1
# Controller
...
redirect_to url_for(params[:redirect_to].merge(:only_path => true))
Adopting the above approach users can be redirected after performing an action. However, I think people can enter arbitraryparams that can lead to security issues...
Is it safe to accept URL parameters for populating the url_for method? What are pitfalls? What can happen in the worst case?
By logging params during requests to my application I noted Rails adds always :controller and action parameters. Maybe that confirms url_for can be used the above way since it is protected internally and works as-like Rails is intended to.
This it is safe internally as Ruby On Rails will only be issuing a HTTP redirect response.
As you are using only_path this will protect you from an Open redirect vulnerability. This is where an email is sent by an attacker containing a link in the following format (say your site is example.com).
https://example.com?foo=bar&bar=foo&redirect=http://evil.com
As the user checks the URL and sees it is on the example.com domain they beleive it is safe so click the link. However, if there's an open redirect then the user ends up on evil.com which could ask for their example.com password without the user noticing.
Redirecting to a relative path only on your site fixes any vulnerability.
In your case you are giving users control of your controller, action and parameters. As long as your GET methods are safe (i.e. no side-effects), an attacker could not use this by creating a crafted link that the user opens.
In summary, from the information provided I don't see any risk from phishing URLs to your application.
Rails redirect_to sets the HTTP status code to 302 Found which tells the browser to GET the new path as you defined it by url_for. GET is a considered a safe method in contrast to
... methods such as POST, PUT, DELETE and PATCH [which] are intended for
actions that may cause side effects either on the server, or external
side effects ...
The only problem would have been if someone could gain access to methods such as create and destroy. Since these methods use HTTP methods other than GET (respectively POST and DELETE) it should be no problem.
Another danger here is if you go beyond CRUD methods of REST and have a custom method which responses to GET and changes the database state:
routes.rb
resources something do
member do
get :my_action
end
end
SomethingController
def my_action
# delte some records
end
For future ref:
Rails has a number of security measurements which may also interest you.
It's not exactly an answer, just wanted to point out that you shouldn't use something like
url_for(params)
because one could pass host and port as params and thus the url could lead to another site and it can get worse if it gets cached or something.
Don't know if it threatens anything, but hey, it's worth pointing out

Which HTTP method should I use for request that can create or simply read a resource?

In my Rails application I have an url routed to an action in charged of showing or creating (if not existing) e resource. What is the appropriate http verb to use for this kind of request?
To be more precise, in my method I don't directly access the resource but I use a library which has that behavior: first search and then create the resource if not exiting. My method, in the end, always provide the resource returned by the library either a brand new one or an old one. Hence I cannot split into two requests.
According to this and considering my method always returns the same resource (idempotent) it seems that PUT should be the right one. I just wonder whether PUT can be used in case where e resource is actually just retrieved (get) and anything is not even updated
tnx
POST for creating, GET for showing is automatically used by rails. But I hope you can do all sorts of things with custom programming as data will be available to you in form of params[]
According to Ruby on Rails guides, you should use GET and POST verbs. More information here: http://guides.rubyonrails.org/routing.html#crud-verbs-and-actions
You use GET to retrieve.
If resource found return 200 with resource.
If resource not found let it return 404 and check the error code and use POST and create the resource.
If you donot need any parameter while creating resource then you should use GET request Else if you need params while creating resource , then you should make separate action for creating(Post request with params) and showing(GET request) resource.

how to hit a put route

I have an additional method in one of my otherwise restfull controllers called 'importdata'. As I'm actually changing the data (importing csv in the database), I understood that it should be a put route instead of get.
Initially I had
resource data_set do
put 'importdata', on: :method
end
what I also tried is:
put 'data_sets/:id/importdata', "data_sets#importdata'
rake routes shows the route I want in both cases.
What I did when I had the method on (1st example) route in the controller was
redirect_to import_data_sets_path id: dataset.id
And with the second example:
redirect_to controller: "data_sets", action: "importdata", id: dataset.id
The message I get in both cases is:
No route matches [GET] "/data_sets/28/importdata"
Which is correct, because it's a put route. The only way I get this to work is to change the put for a get:
get 'data_sets/:id/importdata', "data_sets#importdata'
How can I get that to work on a put route? Should it be a put route in the first place?
Thanks for your time.
Simply put you can't 'upgrade' a HTTP request issued by an user. redirects only work over GET. If the user is changing something do it through a form and make sure it's a PUT request as you're modifying an existing resource.
If the PUT is conditional there's several options, either figure out how to solve this in the UI, use an HTTP client to issue the PUT(which doesn't make sense for an local call) or extract the editing of the resource in some other kind of class and use it in the controller.
However, even if the edit is optional it makes more sense to let the user fire a PUT in the first place.
Hope that helps.

Strange Rails resource routes behavior

I've met strange error. Im not sure this is bug. However i never met this strange behavior before.
resource :watches
Makes such strange routing table:
watches POST /watches(.:format) watches#create
new_watches GET /watches/new(.:format) watches#new
edit_watches GET /watches/edit(.:format) watches#edit
GET /watches(.:format) watches#show
PUT /watches(.:format) watches#update
DELETE /watches(.:format) watches#destroy
As you see no ID param and messed actions
On same time:
resources :mibs
Make proper routes
mibs GET /mibs(.:format) mibs#index
POST /mibs(.:format) mibs#create
new_mib GET /mibs/new(.:format) mibs#new
edit_mib GET /mibs/:id/edit(.:format) mibs#edit
mib GET /mibs/:id(.:format) mibs#show
PUT /mibs/:id(.:format) mibs#update
DELETE /mibs/:id(.:format) mibs#destroy
I thought that is could be somehow inflector problem, but trying using "rockets" instead of "watches" give same result:
rockets POST /rockets(.:format) rockets#create
new_rockets GET /rockets/new(.:format) rockets#new
edit_rockets GET /rockets/edit(.:format) rockets#edit
GET /rockets(.:format) rockets#show
PUT /rockets(.:format) rockets#update
DELETE /rockets(.:format) rockets#destroy
Anything except my first two resources (servers and mibs) make such result.
Probably corrupted routing cache somewhere?
resource indicates a singleton resource: in other words, you're telling Rails that there's only ever one watch for each user, so passing IDs would be useless.
resources is the standard invocation for getting routes with IDs attached.
So, essentially, the problem is an inflector one, but for resource or resources, not for the name of your routes. For more information, check out the Ruby on Rails routing guide. It does a good job explaining the difference between singleton resources and the more usual kind.

I got No route matches {:controller=>"refinery/refinery/admin/dashboard"} error

when i hit the url in my local host:
http://localhost:3000/refinery/events
it gets me error:
No route matches {:controller=>"refinery/refinery/admin/dashboard"}
When I go through with rake routes :
events_events GET /events(.:format) refinery/events/events#index
events_event GET /events/:id(.:format) refinery/events/events#show
pdate_positions_events_admin_events POST /refinery/events/update_positions(.:format) refinery/events/admin/events#update_positions
events_admin_events GET /refinery/events(.:format) refinery/events/admin/events#index
POST /refinery/events(.:format) refinery/events/admin/events#create
new_events_admin_event GET /refinery/events/new(.:format) refinery/events/admin/events#new
edit_events_admin_event GET /refinery/events/:id/edit(.:format) refinery/events/admin/events#edit
events_admin_event PUT /refinery/events/:id(.:format) refinery/events/admin/events#update
DELETE /refinery/events/:id(.:format) refinery/events/admin/events#destroy
As I am using the Refinery CMS so there are one routes.rb file in config and also in vendor/extension/ directory.
So how actually they communicate and work it out above ?
You must use resources properly while adding routes . There are two resources which is same .
events and events .
The other problem in this example is sometime GET events understand event id and some times admin in the place of id.
It creates conflict in your route .
Get event/:id and
Get event/admin is creating issue.
Please use rest full routes way, collections and members , name space for admin part so that your code will be more modular.

Resources