Ruby on Rails
LoginGeneratorACLSystem (Version #529)

This example is based on LoginGeneratorAccessControlList (which was based on ACLController).

It uses AccessControlListExample database model and assumes you used the LoginGenerator.

It adds Roles such that

Users <-> Roles <-> Permissions

A User’s permissions are added to their session when they authenticate. Permissions are of the form {controller}/{method}. For example:

posts/add
posts/edit
posts/index   #use this if you want to protect "url/posts" 

Using before_filter :require_login will require the user to have the correct permission string before the action is performed. If the user is unauthorized, they are returned to the requesting page. You may use the :except attribute to allow anyone to access a specific method.

Permissions are kept as part of their session. Any changes made to the User’s permissions will not take effect until they login again. The filters added to this controller will be run for all controllers in the application. Likewise all the methods added be available for all controllers.

To Install:

  1. Follow the directions in HowToQuicklyDoAuthenticationWithLoginGenerator
  2. Create the database schema described in AccessControlListExample
  3. Follow the instructions below:

Put this into lib/acl_system.rb:

# See <a href="http://wiki.rubyonrails.com/rails/show/LoginGeneratorACLSystem">http://wiki.rubyonrails.com/rails/show/LoginGeneratorACLSystem</a>

module ACLSystem
  include LoginSystem

  # This module wires itself into the LoginSystem authorize? method.  You
  # should use the normal:
  #
  #   before_filter :login_required
  #
  # or to leave some actions unprotected:
  #
  #   before_filter :login_required, :except => [ :list, :show ]
  #

  protected

  # Authorizes the user for an action.
  # This works in conjunction with the LoginController.
  # The LoginController loads the User object.
  def authorize?(user)
    required_perm = "%s/%s" % [ params['controller'], params['action'] ]

    if user.authorized? required_perm
      return true
    end

    return false
  end
end

Put this into app/models/permission.rb:

# See <a href="http://wiki.rubyonrails.com/rails/show/AccessControlListExample">http://wiki.rubyonrails.com/rails/show/AccessControlListExample</a>
# and <a href="http://wiki.rubyonrails.com/rails/show/LoginGeneratorAccessControlList">http://wiki.rubyonrails.com/rails/show/LoginGeneratorAccessControlList</a>

class Permission < ActiveRecord::Base
  has_and_belongs_to_many :roles
end

Put this into app/models/role.rb:

# See <a href="http://wiki.rubyonrails.com/rails/show/AccessControlListExample">http://wiki.rubyonrails.com/rails/show/AccessControlListExample</a>
# and <a href="http://wiki.rubyonrails.com/rails/show/LoginGeneratorAccessControlList">http://wiki.rubyonrails.com/rails/show/LoginGeneratorAccessControlList</a>

class Role < ActiveRecord::Base
  has_and_belongs_to_many :permissions
  has_and_belongs_to_many :users
end

Then edit your controllers/application.rb to resemble:

# The filters added to this controller will be run for all controllers in the application.
# Likewise will all the methods added be available for all controllers.

require_dependency "acl_system" 

class ApplicationController < ActionController::Base
  include ACLSystem
  model :user
end

Add the following to your user model:

  has_and_belongs_to_many :roles

  # Return true/false if User is authorized for resource.
  def authorized?(resource)
    return permission_strings.include?(resource)
  end

  # Load permission strings 
  def permission_strings
    a = []
    self.roles.each{|r| r.permissions.each{|p| a<< p.name }}
    a
  end

To use it, just call the normal LoginGenerator filter in your controllers:

before_filter :login_required

or to leave some actions unprotected:
before_filter :login_required, :except => [ :list, :show ]

-JamesHillyerd


QUESTION

How would you distinguish an admin from a regular user?

ANSWER

To distinguish an admin from a regular user you need to add entries to the roles, users_roles, permissions, permissions_roles tables. For two users, moe and curly, identfied with 1 and 2, respectively:

INSERT INTO roles (id, name) VALUES (1, 'admin')
INSERT INTO roles (id, name) VALUES (2, 'regular')

INSERT INTO roles_users (user_id, role_id) VALUES (1, 1)
INSERT INTO roles_users (user_id, role_id) VALUES (2, 2)

INSERT INTO permissions (id, name) VALUES (1, 'admin/index')

INSERT INTO permissions_roles (permission_id, role_id) VALUES (1, 1)

Now, moe has a ‘superuser’ role, this role has permission to do the admin/index action.

-TerryLorber

QUESTION
How do you give the regular user or the admin more permissions?? You can give access to the index action, but it kicks you out for the list action, etc.

QUESTION
This says “A User’s permissions are added to their session when they authenticate.” How does this happen? It looks like the permissions are rebuilt every time authorized? is called.

ANSWER
I think you are correct: the permissions strings are rebuild on each call. I don’t think that ruby actually has to query the database each time, as user.roles should be lazy-loaded once and then cached.

It should be trivial to modify the user object to cache the strings. I’m not actively using this code right now, so if someone else can try it, test it and then modify this page, it would be appreciated!

-JamesHillyerd

A straight forward extension would be to keep permissions as regexp:s and do regexp matching. This would enable you to do compact patterns for an admin.

insert into permissions(name,info) values('.*/.*', 'All access'); 

def authorized?(resource)
    match=false
    permission_strings.each do |p|
      r = Regexp.new(p)
      match = match || ((r =~ resource) != nil)
    end
    return match
end

-FredrikAndersson

I have just extended this with the concept of access-levels.

The short story:

  1. A level-attribute field the permissions_roles table that becomes an extra attribute on the permission.
  2. A :creator-relationship on every object, pointing to the :user-class
  3. Passing an arguments-hash all the way down to the authorized? method in user.rb if !@params[‘id’].nil? (i.e. we’re working on an existing object):
    
    if session[:user] and authorize?(session[:user],:object => @object)
       return true
    end
    

The authorize?-method needs to take a second argument, “arguments”, but just passes it on to user.authorized?

  1. The magic in user.rb:
    Change authorized?-method to:
      def authorized?(resource,arguments)
        if arguments.nil?
          return permission_strings.include?(resource)
        end
        if !arguments[:object].nil?
          return permission_strings.include?(resource) &&
          (permission_levels[resource].to_i.eql?(2) || arguments[:object].creator.id.to_i.eql?(self.id.to_i))
        end
      end
    
      def permission_levels
        b = {}
        self.roles.each do |r|
           r.permissions.each do |p|
            if b.empty? || b[p.name].nil? || p.level.to_i > b[p.name].to_i
              b[p.name] = p.level.to_i
            end
           end
        end
        b
      end
    

Now, the last and least elegant thing in my solution is my current strategy for finding what type of object the ID refers to. I have the controller-name, but how can I use this to find the object with id @params[‘id’] ? For now, I have hard-coded it in login_required in login_system.rb:

    if !params['id'].nil?
      if params['controller'].eql?('news')
        @object = News.find(params['id'])
      end
      if session[:user] and authorize?(session[:user],:object => @object)
        return true
      end
    else
      if session[:user] and authorize?(session[:user],nil)
        return true
      end
    end

How can I find the class-name automagically so that I can use it instead of the hard-coded News.find ?

- VegardEngen

def model_class
  klass_name=Inflector.classify(controller_name)
  Inflector.constantize(klass_name)
end
  ...
  model_class.find(params['id'])

- Simo Addsw.it

QUESTION
Perhaps I’m missing it, very very newby, but is it possible to block access? as in:

Jane has access to the whole house (living room, kitchen, bathroom, bedroom)
John has access to all rooms BUT the bedroom

  Jane gets house/.*
  John gets house/.*  - and - not house/bedroom

thanks!

- Jay Wiggins

ANSWER

Using FredrikAndersson’s regex example above, you can create these permissions:

house/.*
house/[^(bedroom)]

grant the first one to a role of jane’s and the second to a role of john’s.


The above doesn’t work for me but

house/(?!(bedroom))

works.

- Calle Gustafsson

I am getting the following error :

protected method `authorized?' called for #\< User:0x3970708\>

c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.13.0/lib/active_record/base.rb:1494:in `method_missing'
#{RAILS_ROOT}/lib/acl_system.rb:22:in `authorize?'
#{RAILS_ROOT}/lib/login_system.rb:49:in `login_required'

what could be a solution?
Vinit

Rolled back to last good information.

Put the functions authorized? and permission_strings above the “protected” in user.rb
goodi

Updated from @session/@params to session/params
~ ba

Rails newbie here… For some reason after I moved from the simple login authentication to trying ACL I get redirected from my target page to the login page again after I login. Wh at gives??

Bath and Shower
Fragrance
Gift Sets
Hair Care
Makeup
Men’s Grooming
Shaving and Hair Removal
Skin Care
Tools and Accessories

Baby Apparel
Baby Bathing & Skin Care
Baby Bedding
Baby Car Seats
Baby Diapering
Baby Feeding
For Moms
Baby Furniture
Baby Gear
Baby Gifts
Baby Health & Baby Care
Nursery Décor
Potty Training
Baby Safety
Baby Strollers

Books – Business & Investing
Books – Children’s Books
Books – Comics & Graphic Novels
Books – Computers & Internet
Books – Cooking, Food & Wine
Books – Entertainment
Books – Gay & Lesbian
Books – Health, Mind & Body
Books – History
Books – Home & Garden
Books – Law
Books – Literature & Fiction
Books – Medicine
Books – Mystery & Thrillers
Books – Nonfiction
Books – Outdoors & Nature
Books – Parenting & Families
Books – Professional & Technical
Books – Reference
Books – Religion & Spirituality
Books – Romance
Books – Science
Books – Science Fiction & Fantasy
Books – Sports
Books – Teens
Books – Travel

Camera & Photo – Accessories
Camera & Photo – Camcorders
Camera & Photo – Digital Cameras
Camera & Photo – Film Cameras
Camera & Photo – Optics
Camera & Photo – Printers & Scanners

Health & Personal Care – Baby & Child Care
Health & Personal Care – Food & Snacks
Health & Personal Care – Health & Personal Care Outlet Store
Health & Personal Care – Health Care
Health & Personal Care – House Supplies
Health & Personal Care – Nutrition & Fitness
Health & Personal Care – Personal Care
Health & Personal Care – Sexual Wellness

Computers – Computer Add-Ons
Computers – Desktops
Computers – Handhelds & PDAs
Computers – Notebooks

Electronics – Accessories & Supplies
Electronics – Audio & Video
Electronics – Camera & Photo
Electronics – Car Electronics
Electronics – Computers & Add-Ons
Electronics – GPS & Navigation
Electronics – Home Automation & Security
Electronics – Office Electronics
Electronics – Service & Replacement Plans

Gourmet Food – Appetizers & Hors d’oeuvres
Gourmet Food – Baking Supplies
Gourmet Food – Beverages
Gourmet Food – Bread
Gourmet Food – Breakfast Foods
Gourmet Food – Candy
Gourmet Food – Cheese
Gourmet Food – Chocolate
Gourmet Food – Coffee & Tea
Gourmet Food – Cookies
Gourmet Food – Dairy Foods & Eggs
Gourmet Food – Desserts
Gourmet Food – Fruits & Vegetables
Gourmet Food – Gourmet Gifts
Gourmet Food – Jams, Jellies & Preserves
Gourmet Food – Meat, Game & Pâtés
Gourmet Food – Oils, Vinegars & Salad Dressings
Gourmet Food – Pasta, Beans, Grains & Rice
Gourmet Food – Prepared Meals
Gourmet Food – Salsas & Condiments
Gourmet Food – Seafood & Caviar
Gourmet Food – Seasonings, Herbs & Spices
Gourmet Food – Snack Food
Gourmet Food – Soups & Stocks

Grocery – Appetizers & Hors D’Oeuvres
Grocery – Baking Supplies
Grocery – Beverages
Grocery – Boxed Meals & Side Dishes
Grocery – Breads
Grocery – Breakfast Foods
Grocery – Canned & Packaged Goods
Grocery – Coffee, Tea & Cocoa
Grocery – Condiments, Sauces & Spreads
Grocery – Dairy & Eggs
Grocery – Desserts & Pastries
Grocery – Fruits & Vegetables
Grocery – Health & Family
Grocery – Herbs, Spices & Seasonings
Grocery – Household Supplies
Grocery – Meats
Grocery – Pasta & Grains
Grocery – Pet Supplies
Grocery – Seafood
Grocery – Snacks, Cookies & Candy

Home & Garden – Backyard Birding
Home & Garden – Bar Tools & Glasses
Home & Garden – Bedding & Bath
Home & Garden – Coffee, Tea & Espresso
Home & Garden – Cook’s Tools & Gadgets
Home & Garden – Cookware & Baking
Home & Garden – Cutlery
Home & Garden – Fresh Flowers & Indoor Plants
Home & Garden – Furniture & Décor
Home & Garden – Gardening Tools
Home & Garden – Grills, Smokers & Outdoor Cooking
Home & Garden – Heating & Lighting
Home & Garden – Kitchen & Table Linens
Home & Garden – Large Appliances
Home & Garden – Leisure & Fitness
Home & Garden – Outdoor Décor
Home & Garden – Patio Furniture
Home & Garden – Pest Control
Home & Garden – Pet Supplies
Home & Garden – Plants & Planting
Home & Garden – Small Appliances
Home & Garden – Tableware
Home & Garden – Vacuums, Cleaning & Storage
Home & Garden – Weather Instruments
Home & Garden – Wine Accessories

Industrial & Scientific – Adhesive Tapes
Industrial & Scientific – Fasteners
Industrial & Scientific – Industrial Abrasives
Industrial & Scientific – Industrial Adhesives
Industrial & Scientific – Industrial Cutting Tools
Industrial & Scientific – Industrial Hoses
Industrial & Scientific – Material Handling Equipment
Industrial & Scientific – Mechanical Components
Industrial & Scientific – Precision Measurement Products
Industrial & Scientific – Raw Materials

Jewelry – Accessories
Jewelry – Body Jewelry
Jewelry – Bracelets
Jewelry – Brooches & Pins
Jewelry – Charms
Jewelry – Children’s Jewelry
Jewelry – Earrings
Jewelry – Engagement
Jewelry – Jewelry Sets
Jewelry – Men’s Jewelry
Jewelry – Necklaces & Pendants
Jewelry – Religious Jewelry
Jewelry – Rings
Jewelry – Wedding & Anniversary

Kindle Store – Advice & How-to
Kindle Store – Arts & Entertainment
Kindle Store – Biographies & Memoirs
Kindle Store – Business & Investing
Kindle Store – Children’s Chapter Books
Kindle Store – Computers & Internet
Kindle Store – Fantasy
Kindle Store – Fiction
Kindle Store – History
Kindle Store – Humor
Kindle Store – Lifestyle & Home
Kindle Store – Literary Fiction
Kindle Store – Mystery & Thrillers
Kindle Store – Nonfiction
Kindle Store – Parenting & Families
Kindle Store – Politics & Current Events
Kindle Store – Reference
Kindle Store – Religion & Spirituality
Kindle Store – Romance
Kindle Store – Science
Kindle Store – Science Fiction
Kindle Store – Sports
Kindle Store – Travel

Kitchen & Housewares – Bar Tools & Glasses
Kitchen & Housewares – Coffee, Tea & Espresso
Kitchen & Housewares – Cook’s Tools & Gadgets
Kitchen & Housewares – Cookware & Baking
Kitchen & Housewares – Cutlery
Kitchen & Housewares – Dining Room Furniture
Kitchen & Housewares – Kitchen & Table Linens
Kitchen & Housewares – Kitchen Furniture
Kitchen & Housewares – Small Appliances
Kitchen & Housewares – Storage & Organization
Kitchen & Housewares – Tableware
Kitchen & Housewares – Wine Accessories

Magazine Subscriptions – Arts & Crafts
Magazine Subscriptions – Automotive
Magazine Subscriptions – Bridal
Magazine Subscriptions – Business & Finance
Magazine Subscriptions – Children’s
Magazine Subscriptions – Computer & Internet
Magazine Subscriptions – Electronics & Audio
Magazine Subscriptions – Entertainment
Magazine Subscriptions – Family & Parenting
Magazine Subscriptions – Fashion & Style
Magazine Subscriptions – Food & Gourmet
Magazine Subscriptions – Games & Hobbies
Magazine Subscriptions – Gay & Lesbian
Magazine Subscriptions – Health & Fitness
Magazine Subscriptions – History
Magazine Subscriptions – Home & Garden
Magazine Subscriptions – International
Magazine Subscriptions – Lifestyle & Cultures
Magazine Subscriptions – Literary
Magazine Subscriptions – Men’s Interest
Magazine Subscriptions – Music
Magazine Subscriptions – News & Politics
Magazine Subscriptions – Pets
Magazine Subscriptions – Religion & Spirituality
Magazine Subscriptions – Science & Nature
Magazine Subscriptions – Sports & Leisure
Magazine Subscriptions – Teens
Magazine Subscriptions – Travel & Regional
Magazine Subscriptions – Women’s Interest

Miscellaneous – Aircraft
Miscellaneous – Antiques
Miscellaneous – Coins
Miscellaneous – Collectibles
Miscellaneous – General
Miscellaneous – Other Products
Miscellaneous – Scientific Supplies
Miscellaneous – Stamps
Miscellaneous – Vehicles
Miscellaneous – Watercraft

MP3 Downloads – MP3 Albums
MP3 Downloads – MP3 Songs

Music – Alternative Rock
Music – Blues
Music – Broadway & Vocalists
Music – Children’s Music
Music – Christian & Gospel
Music – Classic Rock
Music – Classical
Music – Country
Music – Dance & DJ
Music – Folk
Music – Hard Rock & Metal
Music – International
Music – Jazz
Music – Latin Music
Music – Miscellaneous
Music – New Age
Music – Pop
Music – R&B
Music – Rap & Hip-Hop
Music – Rock
Music – Soundtracks

Classical Music – Ballads
Classical Music – Canons
Classical Music – Concertos
Classical Music – Etudes
Classical Music – Fantasies
Classical Music – Fugues
Classical Music – Improvisation
Classical Music – Inventions
Classical Music – Lullabies & Berceuse
Classical Music – Oratorio
Classical Music – Preludes
Classical Music – Requiems, Elegies & Tombeau
Classical Music – Rondos
Classical Music – Scherzo
Classical Music – Serenades & Divertimentos
Classical Music – Short Forms
Classical Music – Sonatas
Classical Music – Suites
Classical Music – Symphonies
Classical Music – Theatrical, Incidental & Program Music
Classical Music – Toccatas
Classical Music – Variations

Musical Instruments – Band & Orchestra
Musical Instruments – Bass Guitars
Musical Instruments – DJ, Electronic Music & Karaoke
Musical Instruments – Drums & Percussion
Musical Instruments – Folk & World Instruments
Musical Instruments – Guitars
Musical Instruments – Instrument Accessories
Musical Instruments – Keyboards
Musical Instruments – Live Sound & Stage
Musical Instruments – Recording Equipment

Office Products – Business Presentation Supplies
Office Products – Educational Supplies
Office Products – Mailroom Supplies
Office Products – Office Furniture & Accessories
Office Products – Office Lighting
Office Products – Office Supplies

Cell Phones & Service – All
Cell Phones & Service – Bluetooth
Cell Phones & Service – Camera
Cell Phones & Service – E-mail
Cell Phones & Service – Flip
Cell Phones & Service – Kid’s
Cell Phones & Service – Mobile Broadband Cards
Cell Phones & Service – MP3
Cell Phones & Service – PDA
Cell Phones & Service – Prepaid
Cell Phones & Service – Video
Cell Phones & Service – Wi-Fi

Software – Business & Office
Software – Children’s Software
Software – Education & Reference
Software – Graphics
Software – Home & Hobbies
Software – Language & Travel
Software – Linux
Software – Macintosh
Software – Networking
Software – Operating Systems
Software – Outlet
Software – Personal Finance
Software – Programming
Software – Software for Handhelds
Software – Utilities
Software – Video & Music
Software – Web Development

Sports & Outdoors – Accessories
Sports & Outdoors – Airsoft
Sports & Outdoors – Apparel
Sports & Outdoors – Archery
Sports & Outdoors – Badminton
Sports & Outdoors – Ballet & Dance
Sports & Outdoors – Baseball
Sports & Outdoors – Basketball
Sports & Outdoors – Boating
Sports & Outdoors – Bowling
Sports & Outdoors – Boxing
Sports & Outdoors – Camping & Hiking
Sports & Outdoors – Cheerleading
Sports & Outdoors – Climbing
Sports & Outdoors – Crew
Sports & Outdoors – Cricket
Sports & Outdoors – Curling
Sports & Outdoors – Cycling & Wheel Sports
Sports & Outdoors – Disc Sports
Sports & Outdoors – Diving
Sports & Outdoors – Dog Sports
Sports & Outdoors – Equestrian Sports
Sports & Outdoors – Exercise & Fitness
Sports & Outdoors – Fan Shop
Sports & Outdoors – Fencing
Sports & Outdoors – Field Hockey
Sports & Outdoors – Fishing
Sports & Outdoors – Football
Sports & Outdoors – Game Room
Sports & Outdoors – Golf
Sports & Outdoors – Gymnastics
Sports & Outdoors – Hockey
Sports & Outdoors – Hunting
Sports & Outdoors – Jai Alai
Sports & Outdoors – Kayaking
Sports & Outdoors – Lacrosse
Sports & Outdoors – Lawn Games
Sports & Outdoors – Martial Arts
Sports & Outdoors – Motor Sports
Sports & Outdoors – Paddle Court Sports
Sports & Outdoors – Paintball
Sports & Outdoors – Pilates
Sports & Outdoors – Polo
Sports & Outdoors – Racquetball
Sports & Outdoors – Rodeo
Sports & Outdoors – Rugby
Sports & Outdoors – Running
Sports & Outdoors – RV Equipment
Sports & Outdoors – Scooters
Sports & Outdoors – Shoes
Sports & Outdoors – Skateboarding
Sports & Outdoors – Skating
Sports & Outdoors – Skydiving
Sports & Outdoors – Sledding
Sports & Outdoors – Snow Skiing
Sports & Outdoors – Snowboarding
Sports & Outdoors – Snowmobiling
Sports & Outdoors – Snowshoeing
Sports & Outdoors – Soccer
Sports & Outdoors – Softball
Sports & Outdoors – Sports Medicine
Sports & Outdoors – Squash
Sports & Outdoors – Surfing
Sports & Outdoors – Swimming
Sports & Outdoors – Tennis & Racquet Sports
Sports & Outdoors – Track & Field
Sports & Outdoors – Triathlon
Sports & Outdoors – Volleyball
Sports & Outdoors – Water Polo
Sports & Outdoors – Water Sports
Sports & Outdoors – Windsurfing
Sports & Outdoors – Wrestling
Sports & Outdoors – Yoga

Tools & Hardware – Air Tools
Tools & Hardware – Appliances
Tools & Hardware – Building Supplies & Heavy Equipment
Tools & Hardware – Electrical
Tools & Hardware – Hand Tools
Tools & Hardware – Hardware
Tools & Hardware – Heating & Cooling
Tools & Hardware – Home Improvement Outlet
Tools & Hardware – Lawn & Garden
Tools & Hardware – Lighting
Tools & Hardware – Organization & Storage
Tools & Hardware – Painting Tools & Supplies
Tools & Hardware – Plumbing
Tools & Hardware – Power Tool Accessories
Tools & Hardware – Power Tools
Tools & Hardware – Safety & Security

Toys & Games – Action Figures
Toys & Games – Activities & Amusements
Toys & Games – Arts & Crafts
Toys & Games – Bikes, Skates & Ride-Ons
Toys & Games – Construction, Blocks & Models
Toys & Games – Dolls
Toys & Games – Electronics for Kids
Toys & Games – Games
Toys & Games – Hobbies
Toys & Games – Kids’ Furniture & Room Décor
Toys & Games – Learning & Education
Toys & Games – Music
Toys & Games – Party Supplies
Toys & Games – Play Vehicles
Toys & Games – Preschool
Toys & Games – Pretend Play & Dress-up
Toys & Games – Puzzles
Toys & Games – Sports & Outdoor Play
Toys & Games – Stuffed Animals & Plush
Toys & Games – Toy Figures & Playsets

Unbox Video Downloads – International
Unbox Video Downloads – Movies
Unbox Video Downloads – Nonfiction
Unbox Video Downloads – TV

DVD – Action & Adventure
DVD – African American Cinema
DVD – Animation
DVD – Anime & Manga
DVD – Art House & International
DVD – Classics
DVD – Comedy
DVD – Cult Movies
DVD – Documentary
DVD – Drama
DVD – Educational
DVD – Fitness & Yoga
DVD – Gay & Lesbian
DVD – Horror
DVD – Kids & Family
DVD – Military & War
DVD – Music Video & Concerts
DVD – Musicals & Performing Arts
DVD – Mystery & Suspense
DVD – Science Fiction & Fantasy
DVD – Special Interests
DVD – Sports
DVD – Television
DVD – Westerns

Computer & Video Games -

VHS – Action & Adventure
VHS – African American Cinema
VHS – Animation
VHS – Anime & Manga
VHS – Art House & International
VHS – Boxed Sets
VHS – Classics
VHS – Comedy
VHS – Cult Movies
VHS – Documentary
VHS – Drama
VHS – Educational
VHS – Fitness
VHS – Gay & Lesbian
VHS – Horror
VHS – Kids & Family
VHS – Military & War
VHS – Music Video & Concerts
VHS – Musicals & Performing Arts
VHS – Mystery & Suspense
VHS – Science Fiction & Fantasy
VHS – Spanish Language
VHS – Special Interests
VHS – Sports
VHS – Television
VHS – Westerns
VHS – Widescreen

Watches – Accessories
Watches – Casual Watches
Watches – Collectible Watches
Watches – Dress Watches
Watches – Fashion Watches
Watches – Pocket Watches
Watches – Sport Watches

This example is based on LoginGeneratorAccessControlList (which was based on ACLController).

It uses AccessControlListExample database model and assumes you used the LoginGenerator.

It adds Roles such that

Users <-> Roles <-> Permissions

A User’s permissions are added to their session when they authenticate. Permissions are of the form {controller}/{method}. For example:

posts/add
posts/edit
posts/index   #use this if you want to protect "url/posts" 

Using before_filter :require_login will require the user to have the correct permission string before the action is performed. If the user is unauthorized, they are returned to the requesting page. You may use the :except attribute to allow anyone to access a specific method.

Permissions are kept as part of their session. Any changes made to the User’s permissions will not take effect until they login again. The filters added to this controller will be run for all controllers in the application. Likewise all the methods added be available for all controllers.

To Install:

  1. Follow the directions in HowToQuicklyDoAuthenticationWithLoginGenerator
  2. Create the database schema described in AccessControlListExample
  3. Follow the instructions below:

Put this into lib/acl_system.rb:

# See <a href="http://wiki.rubyonrails.com/rails/show/LoginGeneratorACLSystem">http://wiki.rubyonrails.com/rails/show/LoginGeneratorACLSystem</a>

module ACLSystem
  include LoginSystem

  # This module wires itself into the LoginSystem authorize? method.  You
  # should use the normal:
  #
  #   before_filter :login_required
  #
  # or to leave some actions unprotected:
  #
  #   before_filter :login_required, :except => [ :list, :show ]
  #

  protected

  # Authorizes the user for an action.
  # This works in conjunction with the LoginController.
  # The LoginController loads the User object.
  def authorize?(user)
    required_perm = "%s/%s" % [ params['controller'], params['action'] ]

    if user.authorized? required_perm
      return true
    end

    return false
  end
end

Put this into app/models/permission.rb:

# See <a href="http://wiki.rubyonrails.com/rails/show/AccessControlListExample">http://wiki.rubyonrails.com/rails/show/AccessControlListExample</a>
# and <a href="http://wiki.rubyonrails.com/rails/show/LoginGeneratorAccessControlList">http://wiki.rubyonrails.com/rails/show/LoginGeneratorAccessControlList</a>

class Permission < ActiveRecord::Base
  has_and_belongs_to_many :roles
end

Put this into app/models/role.rb:

# See <a href="http://wiki.rubyonrails.com/rails/show/AccessControlListExample">http://wiki.rubyonrails.com/rails/show/AccessControlListExample</a>
# and <a href="http://wiki.rubyonrails.com/rails/show/LoginGeneratorAccessControlList">http://wiki.rubyonrails.com/rails/show/LoginGeneratorAccessControlList</a>

class Role < ActiveRecord::Base
  has_and_belongs_to_many :permissions
  has_and_belongs_to_many :users
end

Then edit your controllers/application.rb to resemble:

# The filters added to this controller will be run for all controllers in the application.
# Likewise will all the methods added be available for all controllers.

require_dependency "acl_system" 

class ApplicationController < ActionController::Base
  include ACLSystem
  model :user
end

Add the following to your user model:

  has_and_belongs_to_many :roles

  # Return true/false if User is authorized for resource.
  def authorized?(resource)
    return permission_strings.include?(resource)
  end

  # Load permission strings 
  def permission_strings
    a = []
    self.roles.each{|r| r.permissions.each{|p| a<< p.name }}
    a
  end

To use it, just call the normal LoginGenerator filter in your controllers:

before_filter :login_required

or to leave some actions unprotected:
before_filter :login_required, :except => [ :list, :show ]

-JamesHillyerd


QUESTION

How would you distinguish an admin from a regular user?

ANSWER

To distinguish an admin from a regular user you need to add entries to the roles, users_roles, permissions, permissions_roles tables. For two users, moe and curly, identfied with 1 and 2, respectively:

INSERT INTO roles (id, name) VALUES (1, 'admin')
INSERT INTO roles (id, name) VALUES (2, 'regular')

INSERT INTO roles_users (user_id, role_id) VALUES (1, 1)
INSERT INTO roles_users (user_id, role_id) VALUES (2, 2)

INSERT INTO permissions (id, name) VALUES (1, 'admin/index')

INSERT INTO permissions_roles (permission_id, role_id) VALUES (1, 1)

Now, moe has a ‘superuser’ role, this role has permission to do the admin/index action.

-TerryLorber

QUESTION
How do you give the regular user or the admin more permissions?? You can give access to the index action, but it kicks you out for the list action, etc.

QUESTION
This says “A User’s permissions are added to their session when they authenticate.” How does this happen? It looks like the permissions are rebuilt every time authorized? is called.

ANSWER
I think you are correct: the permissions strings are rebuild on each call. I don’t think that ruby actually has to query the database each time, as user.roles should be lazy-loaded once and then cached.

It should be trivial to modify the user object to cache the strings. I’m not actively using this code right now, so if someone else can try it, test it and then modify this page, it would be appreciated!

-JamesHillyerd

A straight forward extension would be to keep permissions as regexp:s and do regexp matching. This would enable you to do compact patterns for an admin.

insert into permissions(name,info) values('.*/.*', 'All access'); 

def authorized?(resource)
    match=false
    permission_strings.each do |p|
      r = Regexp.new(p)
      match = match || ((r =~ resource) != nil)
    end
    return match
end

-FredrikAndersson

I have just extended this with the concept of access-levels.

The short story:

  1. A level-attribute field the permissions_roles table that becomes an extra attribute on the permission.
  2. A :creator-relationship on every object, pointing to the :user-class
  3. Passing an arguments-hash all the way down to the authorized? method in user.rb if !@params[‘id’].nil? (i.e. we’re working on an existing object):
    
    if session[:user] and authorize?(session[:user],:object => @object)
       return true
    end
    

The authorize?-method needs to take a second argument, “arguments”, but just passes it on to user.authorized?

  1. The magic in user.rb:
    Change authorized?-method to:
      def authorized?(resource,arguments)
        if arguments.nil?
          return permission_strings.include?(resource)
        end
        if !arguments[:object].nil?
          return permission_strings.include?(resource) &&
          (permission_levels[resource].to_i.eql?(2) || arguments[:object].creator.id.to_i.eql?(self.id.to_i))
        end
      end
    
      def permission_levels
        b = {}
        self.roles.each do |r|
           r.permissions.each do |p|
            if b.empty? || b[p.name].nil? || p.level.to_i > b[p.name].to_i
              b[p.name] = p.level.to_i
            end
           end
        end
        b
      end
    

Now, the last and least elegant thing in my solution is my current strategy for finding what type of object the ID refers to. I have the controller-name, but how can I use this to find the object with id @params[‘id’] ? For now, I have hard-coded it in login_required in login_system.rb:

    if !params['id'].nil?
      if params['controller'].eql?('news')
        @object = News.find(params['id'])
      end
      if session[:user] and authorize?(session[:user],:object => @object)
        return true
      end
    else
      if session[:user] and authorize?(session[:user],nil)
        return true
      end
    end

How can I find the class-name automagically so that I can use it instead of the hard-coded News.find ?

- VegardEngen

def model_class
  klass_name=Inflector.classify(controller_name)
  Inflector.constantize(klass_name)
end
  ...
  model_class.find(params['id'])

- Simo Addsw.it

QUESTION
Perhaps I’m missing it, very very newby, but is it possible to block access? as in:

Jane has access to the whole house (living room, kitchen, bathroom, bedroom)
John has access to all rooms BUT the bedroom

  Jane gets house/.*
  John gets house/.*  - and - not house/bedroom

thanks!

- Jay Wiggins

ANSWER

Using FredrikAndersson’s regex example above, you can create these permissions:

house/.*
house/[^(bedroom)]

grant the first one to a role of jane’s and the second to a role of john’s.


The above doesn’t work for me but

house/(?!(bedroom))

works.

- Calle Gustafsson

I am getting the following error :

protected method `authorized?' called for #\< User:0x3970708\>

c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.13.0/lib/active_record/base.rb:1494:in `method_missing'
#{RAILS_ROOT}/lib/acl_system.rb:22:in `authorize?'
#{RAILS_ROOT}/lib/login_system.rb:49:in `login_required'

what could be a solution?
Vinit

Rolled back to last good information.

Put the functions authorized? and permission_strings above the “protected” in user.rb
goodi

Updated from @session/@params to session/params
~ ba

Rails newbie here… For some reason after I moved from the simple login authentication to trying ACL I get redirected from my target page to the login page again after I login. Wh at gives??

Bath and Shower
Fragrance
Gift Sets
Hair Care
Makeup
Men’s Grooming
Shaving and Hair Removal
Skin Care
Tools and Accessories

Baby Apparel
Baby Bathing & Skin Care
Baby Bedding
Baby Car Seats
Baby Diapering
Baby Feeding
For Moms
Baby Furniture
Baby Gear
Baby Gifts
Baby Health & Baby Care
Nursery Décor
Potty Training
Baby Safety
Baby Strollers

Books – Business & Investing
Books – Children’s Books
Books – Comics & Graphic Novels
Books – Computers & Internet
Books – Cooking, Food & Wine
Books – Entertainment
Books – Gay & Lesbian
Books – Health, Mind & Body
Books – History
Books – Home & Garden
Books – Law
Books – Literature & Fiction
Books – Medicine
Books – Mystery & Thrillers
Books – Nonfiction
Books – Outdoors & Nature
Books – Parenting & Families
Books – Professional & Technical
Books – Reference
Books – Religion & Spirituality
Books – Romance
Books – Science
Books – Science Fiction & Fantasy
Books – Sports
Books – Teens
Books – Travel

Camera & Photo – Accessories
Camera & Photo – Camcorders
Camera & Photo – Digital Cameras
Camera & Photo – Film Cameras
Camera & Photo – Optics
Camera & Photo – Printers & Scanners

Health & Personal Care – Baby & Child Care
Health & Personal Care – Food & Snacks
Health & Personal Care – Health & Personal Care Outlet Store
Health & Personal Care – Health Care
Health & Personal Care – House Supplies
Health & Personal Care – Nutrition & Fitness
Health & Personal Care – Personal Care
Health & Personal Care – Sexual Wellness

Computers – Computer Add-Ons
Computers – Desktops
Computers – Handhelds & PDAs
Computers – Notebooks

Electronics – Accessories & Supplies
Electronics – Audio & Video
Electronics – Camera & Photo
Electronics – Car Electronics
Electronics – Computers & Add-Ons
Electronics – GPS & Navigation
Electronics – Home Automation & Security
Electronics – Office Electronics
Electronics – Service & Replacement Plans

Gourmet Food – Appetizers & Hors d’oeuvres
Gourmet Food – Baking Supplies
Gourmet Food – Beverages
Gourmet Food – Bread
Gourmet Food – Breakfast Foods
Gourmet Food – Candy
Gourmet Food – Cheese
Gourmet Food – Chocolate
Gourmet Food – Coffee & Tea
Gourmet Food – Cookies
Gourmet Food – Dairy Foods & Eggs
Gourmet Food – Desserts
Gourmet Food – Fruits & Vegetables
Gourmet Food – Gourmet Gifts
Gourmet Food – Jams, Jellies & Preserves
Gourmet Food – Meat, Game & Pâtés
Gourmet Food – Oils, Vinegars & Salad Dressings
Gourmet Food – Pasta, Beans, Grains & Rice
Gourmet Food – Prepared Meals
Gourmet Food – Salsas & Condiments
Gourmet Food – Seafood & Caviar
Gourmet Food – Seasonings, Herbs & Spices
Gourmet Food – Snack Food
Gourmet Food – Soups & Stocks

Grocery – Appetizers & Hors D’Oeuvres
Grocery – Baking Supplies
Grocery – Beverages
Grocery – Boxed Meals & Side Dishes
Grocery – Breads
Grocery – Breakfast Foods
Grocery – Canned & Packaged Goods
Grocery – Coffee, Tea & Cocoa
Grocery – Condiments, Sauces & Spreads
Grocery – Dairy & Eggs
Grocery – Desserts & Pastries
Grocery – Fruits & Vegetables
Grocery – Health & Family
Grocery – Herbs, Spices & Seasonings
Grocery – Household Supplies
Grocery – Meats
Grocery – Pasta & Grains
Grocery – Pet Supplies
Grocery – Seafood
Grocery – Snacks, Cookies & Candy

Home & Garden – Backyard Birding
Home & Garden – Bar Tools & Glasses
Home & Garden – Bedding & Bath
Home & Garden – Coffee, Tea & Espresso
Home & Garden – Cook’s Tools & Gadgets
Home & Garden – Cookware & Baking
Home & Garden – Cutlery
Home & Garden – Fresh Flowers & Indoor Plants
Home & Garden – Furniture & Décor
Home & Garden – Gardening Tools
Home & Garden – Grills, Smokers & Outdoor Cooking
Home & Garden – Heating & Lighting
Home & Garden – Kitchen & Table Linens
Home & Garden – Large Appliances
Home & Garden – Leisure & Fitness
Home & Garden – Outdoor Décor
Home & Garden – Patio Furniture
Home & Garden – Pest Control
Home & Garden – Pet Supplies
Home & Garden – Plants & Planting
Home & Garden – Small Appliances
Home & Garden – Tableware
Home & Garden – Vacuums, Cleaning & Storage
Home & Garden – Weather Instruments
Home & Garden – Wine Accessories

Industrial & Scientific – Adhesive Tapes
Industrial & Scientific – Fasteners
Industrial & Scientific – Industrial Abrasives
Industrial & Scientific – Industrial Adhesives
Industrial & Scientific – Industrial Cutting Tools
Industrial & Scientific – Industrial Hoses
Industrial & Scientific – Material Handling Equipment
Industrial & Scientific – Mechanical Components
Industrial & Scientific – Precision Measurement Products
Industrial & Scientific – Raw Materials

Jewelry – Accessories
Jewelry – Body Jewelry
Jewelry – Bracelets
Jewelry – Brooches & Pins
Jewelry – Charms
Jewelry – Children’s Jewelry
Jewelry – Earrings
Jewelry – Engagement
Jewelry – Jewelry Sets
Jewelry – Men’s Jewelry
Jewelry – Necklaces & Pendants
Jewelry – Religious Jewelry
Jewelry – Rings
Jewelry – Wedding & Anniversary

Kindle Store – Advice & How-to
Kindle Store – Arts & Entertainment
Kindle Store – Biographies & Memoirs
Kindle Store – Business & Investing
Kindle Store – Children’s Chapter Books
Kindle Store – Computers & Internet
Kindle Store – Fantasy
Kindle Store – Fiction
Kindle Store – History
Kindle Store – Humor
Kindle Store – Lifestyle & Home
Kindle Store – Literary Fiction
Kindle Store – Mystery & Thrillers
Kindle Store – Nonfiction
Kindle Store – Parenting & Families
Kindle Store – Politics & Current Events
Kindle Store – Reference
Kindle Store – Religion & Spirituality
Kindle Store – Romance
Kindle Store – Science
Kindle Store – Science Fiction
Kindle Store – Sports
Kindle Store – Travel

Kitchen & Housewares – Bar Tools & Glasses
Kitchen & Housewares – Coffee, Tea & Espresso
Kitchen & Housewares – Cook’s Tools & Gadgets
Kitchen & Housewares – Cookware & Baking
Kitchen & Housewares – Cutlery
Kitchen & Housewares – Dining Room Furniture
Kitchen & Housewares – Kitchen & Table Linens
Kitchen & Housewares – Kitchen Furniture
Kitchen & Housewares – Small Appliances
Kitchen & Housewares – Storage & Organization
Kitchen & Housewares – Tableware
Kitchen & Housewares – Wine Accessories

Magazine Subscriptions – Arts & Crafts
Magazine Subscriptions – Automotive
Magazine Subscriptions – Bridal
Magazine Subscriptions – Business & Finance
Magazine Subscriptions – Children’s
Magazine Subscriptions – Computer & Internet
Magazine Subscriptions – Electronics & Audio
Magazine Subscriptions – Entertainment
Magazine Subscriptions – Family & Parenting
Magazine Subscriptions – Fashion & Style
Magazine Subscriptions – Food & Gourmet
Magazine Subscriptions – Games & Hobbies
Magazine Subscriptions – Gay & Lesbian
Magazine Subscriptions – Health & Fitness
Magazine Subscriptions – History
Magazine Subscriptions – Home & Garden
Magazine Subscriptions – International
Magazine Subscriptions – Lifestyle & Cultures
Magazine Subscriptions – Literary
Magazine Subscriptions – Men’s Interest
Magazine Subscriptions – Music
Magazine Subscriptions – News & Politics
Magazine Subscriptions – Pets
Magazine Subscriptions – Religion & Spirituality
Magazine Subscriptions – Science & Nature
Magazine Subscriptions – Sports & Leisure
Magazine Subscriptions – Teens
Magazine Subscriptions – Travel & Regional
Magazine Subscriptions – Women’s Interest

Miscellaneous – Aircraft
Miscellaneous – Antiques
Miscellaneous – Coins
Miscellaneous – Collectibles
Miscellaneous – General
Miscellaneous – Other Products
Miscellaneous – Scientific Supplies
Miscellaneous – Stamps
Miscellaneous – Vehicles
Miscellaneous – Watercraft

MP3 Downloads – MP3 Albums
MP3 Downloads – MP3 Songs

Music – Alternative Rock
Music – Blues
Music – Broadway & Vocalists
Music – Children’s Music
Music – Christian & Gospel
Music – Classic Rock
Music – Classical
Music – Country
Music – Dance & DJ
Music – Folk
Music – Hard Rock & Metal
Music – International
Music – Jazz
Music – Latin Music
Music – Miscellaneous
Music – New Age
Music – Pop
Music – R&B
Music – Rap & Hip-Hop
Music – Rock
Music – Soundtracks

Classical Music – Ballads
Classical Music – Canons
Classical Music – Concertos
Classical Music – Etudes
Classical Music – Fantasies
Classical Music – Fugues
Classical Music – Improvisation
Classical Music – Inventions
Classical Music – Lullabies & Berceuse
Classical Music – Oratorio
Classical Music – Preludes
Classical Music – Requiems, Elegies & Tombeau
Classical Music – Rondos
Classical Music – Scherzo
Classical Music – Serenades & Divertimentos
Classical Music – Short Forms
Classical Music – Sonatas
Classical Music – Suites
Classical Music – Symphonies
Classical Music – Theatrical, Incidental & Program Music
Classical Music – Toccatas
Classical Music – Variations

Musical Instruments – Band & Orchestra
Musical Instruments – Bass Guitars
Musical Instruments – DJ, Electronic Music & Karaoke
Musical Instruments – Drums & Percussion
Musical Instruments – Folk & World Instruments
Musical Instruments – Guitars
Musical Instruments – Instrument Accessories
Musical Instruments – Keyboards
Musical Instruments – Live Sound & Stage
Musical Instruments – Recording Equipment

Office Products – Business Presentation Supplies
Office Products – Educational Supplies
Office Products – Mailroom Supplies
Office Products – Office Furniture & Accessories
Office Products – Office Lighting
Office Products – Office Supplies

Cell Phones & Service – All
Cell Phones & Service – Bluetooth
Cell Phones & Service – Camera
Cell Phones & Service – E-mail
Cell Phones & Service – Flip
Cell Phones & Service – Kid’s
Cell Phones & Service – Mobile Broadband Cards
Cell Phones & Service – MP3
Cell Phones & Service – PDA
Cell Phones & Service – Prepaid
Cell Phones & Service – Video
Cell Phones & Service – Wi-Fi

Software – Business & Office
Software – Children’s Software
Software – Education & Reference
Software – Graphics
Software – Home & Hobbies
Software – Language & Travel
Software – Linux
Software – Macintosh
Software – Networking
Software – Operating Systems
Software – Outlet
Software – Personal Finance
Software – Programming
Software – Software for Handhelds
Software – Utilities
Software – Video & Music
Software – Web Development

Sports & Outdoors – Accessories
Sports & Outdoors – Airsoft
Sports & Outdoors – Apparel
Sports & Outdoors – Archery
Sports & Outdoors – Badminton
Sports & Outdoors – Ballet & Dance
Sports & Outdoors – Baseball
Sports & Outdoors – Basketball
Sports & Outdoors – Boating
Sports & Outdoors – Bowling
Sports & Outdoors – Boxing
Sports & Outdoors – Camping & Hiking
Sports & Outdoors – Cheerleading
Sports & Outdoors – Climbing
Sports & Outdoors – Crew
Sports & Outdoors – Cricket
Sports & Outdoors – Curling
Sports & Outdoors – Cycling & Wheel Sports
Sports & Outdoors – Disc Sports
Sports & Outdoors – Diving
Sports & Outdoors – Dog Sports
Sports & Outdoors – Equestrian Sports
Sports & Outdoors – Exercise & Fitness
Sports & Outdoors – Fan Shop
Sports & Outdoors – Fencing
Sports & Outdoors – Field Hockey
Sports & Outdoors – Fishing
Sports & Outdoors – Football
Sports & Outdoors – Game Room
Sports & Outdoors – Golf
Sports & Outdoors – Gymnastics
Sports & Outdoors – Hockey
Sports & Outdoors – Hunting
Sports & Outdoors – Jai Alai
Sports & Outdoors – Kayaking
Sports & Outdoors – Lacrosse
Sports & Outdoors – Lawn Games
Sports & Outdoors – Martial Arts
Sports & Outdoors – Motor Sports
Sports & Outdoors – Paddle Court Sports
Sports & Outdoors – Paintball
Sports & Outdoors – Pilates
Sports & Outdoors – Polo
Sports & Outdoors – Racquetball
Sports & Outdoors – Rodeo
Sports & Outdoors – Rugby
Sports & Outdoors – Running
Sports & Outdoors – RV Equipment
Sports & Outdoors – Scooters
Sports & Outdoors – Shoes
Sports & Outdoors – Skateboarding
Sports & Outdoors – Skating
Sports & Outdoors – Skydiving
Sports & Outdoors – Sledding
Sports & Outdoors – Snow Skiing
Sports & Outdoors – Snowboarding
Sports & Outdoors – Snowmobiling
Sports & Outdoors – Snowshoeing
Sports & Outdoors – Soccer
Sports & Outdoors – Softball
Sports & Outdoors – Sports Medicine
Sports & Outdoors – Squash
Sports & Outdoors – Surfing
Sports & Outdoors – Swimming
Sports & Outdoors – Tennis & Racquet Sports
Sports & Outdoors – Track & Field
Sports & Outdoors – Triathlon
Sports & Outdoors – Volleyball
Sports & Outdoors – Water Polo
Sports & Outdoors – Water Sports
Sports & Outdoors – Windsurfing
Sports & Outdoors – Wrestling
Sports & Outdoors – Yoga

Tools & Hardware – Air Tools
Tools & Hardware – Appliances
Tools & Hardware – Building Supplies & Heavy Equipment
Tools & Hardware – Electrical
Tools & Hardware – Hand Tools
Tools & Hardware – Hardware
Tools & Hardware – Heating & Cooling
Tools & Hardware – Home Improvement Outlet
Tools & Hardware – Lawn & Garden
Tools & Hardware – Lighting
Tools & Hardware – Organization & Storage
Tools & Hardware – Painting Tools & Supplies
Tools & Hardware – Plumbing
Tools & Hardware – Power Tool Accessories
Tools & Hardware – Power Tools
Tools & Hardware – Safety & Security

Toys & Games – Action Figures
Toys & Games – Activities & Amusements
Toys & Games – Arts & Crafts
Toys & Games – Bikes, Skates & Ride-Ons
Toys & Games – Construction, Blocks & Models
Toys & Games – Dolls
Toys & Games – Electronics for Kids
Toys & Games – Games
Toys & Games – Hobbies
Toys & Games – Kids’ Furniture & Room Décor
Toys & Games – Learning & Education
Toys & Games – Music
Toys & Games – Party Supplies
Toys & Games – Play Vehicles
Toys & Games – Preschool
Toys & Games – Pretend Play & Dress-up
Toys & Games – Puzzles
Toys & Games – Sports & Outdoor Play
Toys & Games – Stuffed Animals & Plush
Toys & Games – Toy Figures & Playsets

Unbox Video Downloads – International
Unbox Video Downloads – Movies
Unbox Video Downloads – Nonfiction
Unbox Video Downloads – TV

DVD – Action & Adventure
DVD – African American Cinema
DVD – Animation
DVD – Anime & Manga
DVD – Art House & International
DVD – Classics
DVD – Comedy
DVD – Cult Movies
DVD – Documentary
DVD – Drama
DVD – Educational
DVD – Fitness & Yoga
DVD – Gay & Lesbian
DVD – Horror
DVD – Kids & Family
DVD – Military & War
DVD – Music Video & Concerts
DVD – Musicals & Performing Arts
DVD – Mystery & Suspense
DVD – Science Fiction & Fantasy
DVD – Special Interests
DVD – Sports
DVD – Television
DVD – Westerns

Computer & Video Games -

VHS – Action & Adventure
VHS – African American Cinema
VHS – Animation
VHS – Anime & Manga
VHS – Art House & International
VHS – Boxed Sets
VHS – Classics
VHS – Comedy
VHS – Cult Movies
VHS – Documentary
VHS – Drama
VHS – Educational
VHS – Fitness
VHS – Gay & Lesbian
VHS – Horror
VHS – Kids & Family
VHS – Military & War
VHS – Music Video & Concerts
VHS – Musicals & Performing Arts
VHS – Mystery & Suspense
VHS – Science Fiction & Fantasy
VHS – Spanish Language
VHS – Special Interests
VHS – Sports
VHS – Television
VHS – Westerns
VHS – Widescreen

Watches – Accessories
Watches – Casual Watches
Watches – Collectible Watches
Watches – Dress Watches
Watches – Fashion Watches
Watches – Pocket Watches
Watches – Sport Watches