Plugins - FilePermissions

StarAdd to favorites

FilePermissions

Use this plugin if you want to fine-tune permissions on some or all the files in your public directory.

Normally these files are served by the webserver before Rails ever gets a chance to see the request. This plugin tells the webserver to pass certain file requests on to Rails, where a before_filter intercepts them and passes them to a callback you provide to determine whether you would like to serve them or not. It provides a handy controller method that lets you serve the file efficiently, complete with flexible cache-control support.

Example

You can register the files you are interested in anywhere, really, but it probably makes the most sense to put it in app/controllers/application.rb, together with the before_filter, so that it’s all in one place:

  class ApplicationController < ActionController::Base

    # Make sure we've had a chance to login the user, first, if we support
    # "remember-me" style login via cookies.
    before_filter :autologin

    # Now intercept file requests and evaluate permissions.
    before_filter :file_permissions

    # Simplest example: just check if the current user has permission to see
    # a given file.  It serves the file automatically if you return true,
    # otherwise it renders /public/403.html (this is not supplied with Rails).
    FilePermissions.register("/public/images/user") do |controller, file|
      controller.session[:user].has_permission_to_view_image(file)
    end

    # You may customize things very easily: This time we look up the Image
    # object associated with our images, query a database to see if the current
    # user has access.  If they do, render it, but instruct the browser to keep
    # the image in a private cache, and tell it to revalidate once a day.  If
    # the user does not have access, render the "access_denied" view.
    FilePermissions.register(/public.images.user.(\d+).jpg$/) do |controller, file, match|
      if (img = Image.find(match[1])) &&
          img.can_user_see_me?(controller.session[:user])
        controller.render_file(file,
          :private => true,
          :max_age => 1.day,
          :must_revalidate => true
        )
      else
        controller.render(:action => "access_denied")
      end
    end
  end

Limitations

Currently it only works with Mongrel. But it should be relatively easy to hack Webrick or any other Ruby webservers the same way we’ve done Mongrel.

You will need to make sure there is a route defined for the files you are protecting. I recommend something like what’s shown below to capture everything under a given directory. Remember, it doesn’t actually ever reach the bogus action. In fact, even the controller is unimportant if you place before_filter :file_permissions in ApplicationController.

  ActionController::Routing::Routes.draw do |map|
    # Route everything under /images to "anycontroller".
    map.connect "/images/*file", :controller => "anycontroller", :action => "bogus"
  end

If you are running Mongrel under Apache, then you will further need to instruct Apache to pass these files. Typically this is done in the configuration file using ProxyPass directives. For example, a typical configuration might look like this:

  <VirtualHost *:80>
    ServerName    yourdomain.com
    DocumentRoot  "/usr/local/rails/yourdomain"
    SetEnv        RAILS_ENV production

    <Directory /usr/local/rails/yourdomain>
      Options FollowSymLinks
      AllowOverride AuthConfig Limit
      Order allow,deny
      Allow from all
    </Directory>

    # Tell Apache to pass requests for user images on to Rails.
    ProxyPass /images/user balancer://mongrel_cluster/

    # Everything else in public is okay to serve up as-is.
    ProxyPass /images      !
    ProxyPass /stylesheets !
    ProxyPass /javascripts !
    ProxyPass /robots.txt  !
    ProxyPass /favicon.ico !

    # Everything else goes to Rails.
    ProxyPass / balancer://mongrel_cluster/
    ProxyPreserveHost on

    <Proxy balancer://mongrel_cluster>
      BalancerMember http://127.0.0.1:3000
      BalancerMember http://127.0.0.1:3001
      BalancerMember http://127.0.0.1:3002
    </Proxy>

    RewriteEngine on

    etc...
  </VirtualHost>
Author:Jason Hollinger
License:Free - do whatever you want to with it.
Last Update:July 30, 2008

Jason Hollinger

http://bornnaturalist.org/svn/plugins/file_permissions/

PublicDomain

  • Currently 0.0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Security

Tags

Comments

Add a comment

Search Plugins

Query syntax

Plugins by Category

Sponsors

Rails Kits: Get Code. Get Moving.

Have a comment?