Sorry if this is a noob question on oauth
I've implemented an oauth2 API with devise+doorkeeper based on the examples here: https://doorkeeper-provider.herokuapp.com/ and here: https://github.com/applicake/doorkeeper-devise-client
I want to be able to provide an API endpoint that returns a list of deals that's paginatable, the code is the following:
module Api::V1
class DealsController < ApiController
doorkeeper_for :index
doorkeeper_for :create, :scopes => [:write]
respond_to :json
def index
if params[:page].nil?
page = 1
else
page = params[:page].to_i
end
respond_with Deal.page(page).order("published DESC")
end
def create
respond_with 'api_v1', Deal.create!(params[:deal])
end
end
end
However, on the client side, I cannot pass a page param with something like this:
/explore/deals.json?page=3
The page param is not seen in the provider for some reason. Can someone help me please?
I realized the problem is in the api_controller of doorkeeper-devise-client
The page param isn't passed correctly. Making the following change fixes the problem:
class ApiController < ApplicationController
respond_to :json
def explore
api_call = params[:api]
if !params[:page].nil?
api_call << "/?page=#{params[:page]}"
end
#json = doorkeeper_access_token.get("api/v1/#{api_call}").parsed
respond_with #json
end
end
Related
I am trying to send a post request to the provider using doorkeeper. I created the application and token, my get request to the api works perfectly:
access_token.get("/api/v1/groups")
But the post gives me a long error which includes InvalidAuthenticityToken error.
access_token.post("/api/v1/groups", params: {group: {title: "Title 1"}})
I post the error here post request error link
This is my controller:
module Api
module V1
class GroupsController < BaseController
doorkeeper_for :all
def index
render json: current_user.groups
end
def create
render json: current_user.groups.create(group_params)
end
private
def group_params
params.require(:group).permit(:title, :description, :header_image, :privatization, :amount, :currency, :rate, :max_paiment)
end
end
end
end
Any feedback will be really appreciated, Thanks!
putting protect_from_forgery with: :null_session in your controller should solve the problem
New to rails 3
I would like to create a contact form that people fill out, its saved to the db and then a thank you page comes up.
I would like to do this without scaffold so I can learn better, and I figure that by doing it this way it would be easer to setup so that people cannot try and look at other people's entries by modifying the url.
ideally it would keep their state in the session or cookie so that they would end up on the thanks page if they came back.
Have been trying to do this for about 3 days and reading/googling tons, but between the new routes redirect_to controller stuff in rails3 havn't managed to figure it out.
Routes.rb
Contact::Application.routes.draw do
resources :contactees, :only => [:new, :create]
# to make sure crud doesn't have the routest I don't want
get 'contactees/submitted'
root :to => 'contactees#new'
contactees_controller.rb
ContacteesController < ApplicationControler
def share
end
def new
#contactee = Contactee.new
end
def create
#contactee = Contactee.new(params[:contactee])
if #contactee.save
redirect_to submitted_contactee
else
render action: "new"
end
end
end
Views
contactees
_form.html.erb
new.html.erb
submitted.html.erb
Get rid of the submitted route, you don't need it. Perhaps something like this?
def new
render :submitted if session[:contacted]
end
def create
#contactee = Contactee.new(params[:contactee])
if #contactee.save
session[:contacted] = true
render :submitted
else
render action: "new"
end
end
Why doesn't respond_with respond with the json in this case? I'm invoking the action with an explicit .json (/tasks/4e3c1163a19d461203000106/items/4e4c27dfa19d46e0e400000a.json)
In my controller --
class Tasks::TasksController < Tasks::BaseController
respond_to :html, :js, :json
def update
#task = #taskgroup.update_task(params[:id], params[:task])
#taskgroup.save
respond_with #task
end
end
When I overrode to_json and added a breakpoint, it isn't hit. The response is:
{}
If I replace respond_with with an explicit call to to_json:
respond_with #task do |format|
format.json { render json: #task.to_json }
end
The response is perfect:
{
"_id":"4e4c27dfa19d46e0e400000a",
"assigned_to":null,
"comments" [{"_id":"4e4c2fd7a19d46e127000014",
[SNIP]
It works fine in the later case, but I'd like to figure out why the first one doesn't work. This happens for other controllers and models in my app. Not sure if its a mongoid thing? (rails 3.0.9 / mongoid 2.1.8)
Here is a monkeypatch I wrote to always respond_with what you tell it to do regardless of protocol. Be warned this does break RESTful best practices and if you respond_with in a RESTful manner then it may break. However if your JSON/XML responses are separate from the main application then it is useful and your other controllers will not break.
Usage, Include this in any controller to override the respond_with functionality.
class ApiController < BaseController
include ValidResponder
end
Then anything that extends ApiController will include this functionality.
Save the following in app/lib/valid_responder.rb:
#Override restful responses.
module ValidResponder
def self.included(base)
ActionController::Responder.class_eval do
alias :old_api_behavior :api_behavior
define_method :api_behavior do |error|
if controller.class.ancestors.include?(base)
raise error unless resourceful?
display resource
else
old_api_behaviour(error)
end
end
end
end
end
For reference, the actual method source is available here: http://api.rubyonrails.org/classes/ActionController/Responder.html#method-i-api_behavior
Ok look how it goes. When you call respond_with inside the update action then (if the object is valid) it will redirect to the show action (if you do not want this default behaviour you must provide location: "other_action" to respond_with).
Is it possible to access parameters passed in the url in CanCan? I'm trying to authenticate guests based on a token in the url.
Thanks!
I recently achieved something similar using the method described here:
https://github.com/ryanb/cancan/wiki/Accessing-request-data
In my case, it looked something like this:
app/controllers/application_controller.rb:
class ApplicationController < ActionController::Base
...
def current_ability
#current_ability ||= Ability.new(current_user, params[:token])
end
end
app/models/ability.rb:
class Ability
include CanCan::Ability
def initialize(user, token=nil)
...
can :read, Article, :tokens => { :token => token }
...
end
end
Currently, we are using something similar to
authorize! action, resource, session[:access_token] in a before filter - from this page: http://spreecommerce.com/documentation/security.html
I'm new to Rails, and a bit confused about routes:
I have a Devices controller:
#devices_controllers.rb
class DevicesController < ApplicationController
def index
#devices = Device.all
end
def show
#device = Device.find(params[:id])
end
def new
#device = Device.new
end
def create
#device = Device.new(params[:device])
if #device.save
flash[:notice] = "Successfully created device."
redirect_to #device
else
render :action => 'new'
end
end
def edit
#device = Device.find(params[:id])
end
def update
#device = Device.find(params[:id])
if #device.update_attributes(params[:device])
flash[:notice] = "Successfully updated device."
redirect_to #device
else
render :action => 'edit'
end
end
def destroy
#device = Device.find(params[:id])
#device.destroy
flash[:notice] = "Successfully destroyed device."
redirect_to devices_url
end
def custom_action
"Success"
end
I'd like to access the "custom_action" action via a url like this:
http://foo.bar/devices/custom_action
I've added this line to my routes.rb file:
match 'devices/custom_action' => 'devices#custom_action'
However, when I try the URL in the browser, I get this error:
ActiveRecord::RecordNotFound in DevicesController#show
Couldn't find Device with ID=custom_action
It seems to be going to #show action instead of #custom_action. If a user id is not supplied, and I go to http://foo.bar/devices/custom_action, I'd like it to go #custom_action.
I've read Rails Routing from the Outside, but still can't still seem to figure out the problem.
I think the problem may be because of the order in which you have defined your routes.
I suspect you have resources :devices in your routes.rb. In addition, I suspect you have defined your custom route after this. If you type rake routes into your console/terminal, you will see that there is already a route defined for the following pattern:
GET /devices/:id
This route is a product of resources :devices, which is taking precedence over your custom route. Referring back to the Edge Guides, specifically in 1.1. Connecting URLs to Code, it states that the request will be dispatched to the first matching route. So a simple fix would be to define your custom route before resources :devices.