0

I can't seem to approve authorization for the web_videos_display action. I can make it work by using the skip_authorize_resource but then any user can access the URL for the file by knowing the :id. I need to require access to the asset to "see" the file.

thank you for looking into this.

assets_controller.rb

...
class AssetsController < ApplicationController

  load_and_authorize_resource :team
  load_and_authorize_resource :through => :team

  # skip_authorize_resource :only => [:web_videos_display, ...]
  # skip_authorize_resource :team, :only => [:web_videos_display, ...]
  ...
  def web_videos_display
    # @asset = Asset.find(params[:id]) #loaded by cancan
    @file = "#{Rails.root}#{@asset.webVideos.last.file}"
    send_file @file, :disposition => 'inline', :x_sendfile=>true
  end
  ...

routes.rb

  resources :teams, :path => '', :except => [:index] do
  ...
    resources :assets, :path => '' do
      ...
      get 'web_videos_display'
      ...
    end
  end

show.html.erb

...
<%= team_asset_web_videos_display_path(@team, @asset, :id => @asset.id, :team_id => @team.id) %>
...

ability.rb

...
can :read, Team, :memberships => {:id => user.membership_ids}
can :manage, Asset, :team => { :id => user.team_ids }
can :web_videos_display, Asset, :team => { :id => user.team_ids }
...

update in response to @ryanb comment

that returns

1.9.2p318 :006 > ability.can?(:web_videos_display, asset)
  Team Load (0.2ms)  SELECT "teams".* FROM "teams" WHERE "teams"."id" = 1 LIMIT 1
 => true

but

in development mode it still returns

Started GET "/video-pros/test-1/web_videos_display?id=10" for 127.0.0.1 at 2012-11-09 16:40:19 -0800
  Processing by AssetsController#web_videos_display as */*
  Parameters: {"id"=>"10", "team_id"=>"video-pros", "asset_id"=>"test-1"}
  Team Load (0.1ms)  SELECT "teams".* FROM "teams" WHERE "teams"."slug" = 'video-pros' LIMIT 1
  Team Load (0.2ms)  SELECT "teams".* FROM "teams" WHERE "teams"."admin_user_id" = 1 LIMIT 1
  CACHE (0.0ms)  SELECT "teams".* FROM "teams" WHERE "teams"."slug" = 'video-pros' LIMIT 1
Access denied on show #<Team id: 1, name: "Video Pros", email: nil, phone: nil, website: nil, slug: "video-pros", admin_user_id: 1, created_at: "2012-11-06 22:43:11", updated_at: "2012-11-06 22:43:11", payment_received: nil>
Redirected to http://0.0.0.0:3000/
Completed 302 Found in 73ms>

thanks Ryan

1 Answers1

1

send_file shouldn't make a difference since the authorization happens in a before_filter before the action gets triggered. As far as I can tell it looks correct so there may be something else going on. Have you tried going through this debugging page? What happens if you mimic what the controller authorization is doing in the console?

user = User.first # fetch any user you want to test abilities on
team = Team.first # any model you want to test against
asset = team.assets.first
ability = Ability.new(user)
ability.can?(:show, team) # see if it allows access
ability.can?(:web_videos_display, asset) # see if it allows access

updated :read to :show action for team

ryanb
  • 16,227
  • 5
  • 51
  • 46
  • i updated the original with the output of the console and terminal – T. Weston Kendall Nov 10 '12 at 00:37
  • It appears it is denying access to the parent Team record. Make sure that works in the console too: `ability.can?(:show, team)` – ryanb Nov 10 '12 at 00:45
  • To clarify, the `load_and_authorize_resource :team` line is going to add a before filter to authorize the parent record. If you don't want that you can do `load_resource :team` instead. – ryanb Nov 10 '12 at 00:46