Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

added roles support, authorization plugin

  • Loading branch information...
Josh Adams
Josh Adams committed Nov 16, 2008
1 parent c702121 commit 46ecd79c5a84b191419b7e25735bf7c1e3d99d53
Showing with 1,834 additions and 10 deletions.
  1. +4 −1 app/controllers/admin/base_controller.rb
  2. +12 −0 app/controllers/admin/roles_controller.rb
  3. +4 −1 app/helpers/forms_view_helper.rb
  4. +3 −0 app/models/page.rb
  5. +14 −0 app/models/role.rb
  6. +4 −1 app/models/user.rb
  7. +26 −0 app/views/admin/roles/index.html.erb
  8. +6 −0 config/environment.rb
  9. +1 −0 config/initializers/setup_admin_menu_entries.rb
  10. +7 −4 config/routes.rb
  11. +21 −0 db/migrate/20081116025647_create_roles.rb
  12. +2 −0 lib/tasks/utils.rake
  13. +5 −0 test/fixtures/roles.yml
  14. +10 −0 test/unit/role_test.rb
  15. +1 −0 vendor/plugins/ansuz_theme_installer/app/views/admin/ansuz_theme_installers/index.html.erb
  16. +4 −3 vendor/plugins/ansuz_user_manager/app/views/admin/users/_form.html.erb
  17. +2 −0 vendor/plugins/rails-authorization-plugin/.gitignore
  18. +170 −0 vendor/plugins/rails-authorization-plugin/CHANGELOG.txt
  19. +20 −0 vendor/plugins/rails-authorization-plugin/MIT-LICENSE
  20. +505 −0 vendor/plugins/rails-authorization-plugin/README.rdoc
  21. +35 −0 vendor/plugins/rails-authorization-plugin/README_developers.txt
  22. +22 −0 vendor/plugins/rails-authorization-plugin/Rakefile
  23. +8 −0 vendor/plugins/rails-authorization-plugin/about.yml
  24. BIN vendor/plugins/rails-authorization-plugin/doc/authorization_example.gif
  25. +38 −0 vendor/plugins/rails-authorization-plugin/doc/authorization_example.rb
  26. +35 −0 vendor/plugins/rails-authorization-plugin/generators/role_model/role_model_generator.rb
  27. +5 −0 vendor/plugins/rails-authorization-plugin/generators/role_model/templates/fixtures.yml
  28. +21 −0 vendor/plugins/rails-authorization-plugin/generators/role_model/templates/migration.rb
  29. +8 −0 vendor/plugins/rails-authorization-plugin/generators/role_model/templates/model.rb
  30. +10 −0 vendor/plugins/rails-authorization-plugin/generators/role_model/templates/unit_test.rb
  31. +29 −0 vendor/plugins/rails-authorization-plugin/init.rb
  32. +2 −0 vendor/plugins/rails-authorization-plugin/install.rb
  33. +150 −0 vendor/plugins/rails-authorization-plugin/lib/authorization.rb
  34. +43 −0 vendor/plugins/rails-authorization-plugin/lib/publishare/exceptions.rb
  35. +82 −0 vendor/plugins/rails-authorization-plugin/lib/publishare/hardwired_roles.rb
  36. +121 −0 vendor/plugins/rails-authorization-plugin/lib/publishare/identity.rb
  37. +187 −0 vendor/plugins/rails-authorization-plugin/lib/publishare/object_roles_table.rb
  38. +210 −0 vendor/plugins/rails-authorization-plugin/lib/publishare/parser.rb
  39. +4 −0 vendor/plugins/rails-authorization-plugin/tasks/authorization_tasks.rake
  40. +3 −0 vendor/plugins/rails-authorization-plugin/test/README.txt
@@ -1,7 +1,10 @@
class Admin::BaseController < ApplicationController
layout 'admin'

before_filter :login_required
before_filter :load_admin_plugin_nav
layout 'admin'

permit 'admin'

protected
def load_admin_plugin_nav
@@ -0,0 +1,12 @@
class Admin::RolesController < Admin::BaseController
before_filter :load_roles, :only => [:index]

protected
def load_roles
@roles = Role.root.find(:all)
end

public
def index
end
end
@@ -1,6 +1,9 @@
module FormsViewHelper
def form_row the_label, the_field
def form_row the_label, the_field, options={}
lbl = content_tag("th", the_label)
if options[:note]
the_field << content_tag("div", options[:note], :class => 'note')
end
fld = content_tag("td", the_field)
content_tag("tr", lbl + fld)
end
@@ -29,6 +29,9 @@ class Page < ActiveRecord::Base
before_save :check_page_type, :check_page_order
before_save :ensure_page_metadata

# authorization plugin
acts_as_authorizable

def linked_children
children.select{|x| x.linked? }
end
@@ -0,0 +1,14 @@
# Defines named roles for users that may be applied to
# objects in a polymorphic fashion. For example, you could create a role
# "moderator" for an instance of a model (i.e., an object), a model class,
# or without any specification at all.
class Role < ActiveRecord::Base
has_and_belongs_to_many :users
belongs_to :authorizable, :polymorphic => true

validates_uniqueness_of :name, :scope => [:authorizable_id, :authorizable_type]

STATIC_ROLES = ["admin", "content_owner", "initial_reviewer", "final_reviewer", "author"]

named_scope :root, :conditions => "authorizable_type IS NULL and authorizable_id IS NULL"
end
@@ -18,7 +18,10 @@
class User < ActiveRecord::Base
include SavageBeast::UserInit
# acts_as_taggable_redux support
acts_as_tagger
acts_as_tagger # FIXME: We should switch to http://www.intridea.com/2007/12/4/announcing-acts_as_taggable_on

# authorization plugin
acts_as_authorized_user

# Virtual attribute for the unencrypted password
attr_accessor :password
@@ -0,0 +1,26 @@
<%= title "Roles" %>

<% content_for :sidebar do %>
<div class='note'>
These are the base roles available in the system. There are defaults, but you can feel free to make your own.
</div>
<% end %>

<table class='subdued'>
<thead>
<tr>
<th>Role</th>
<th></th>
</tr>
</thead>
<tbody>
<% @roles.each do |role| -%>
<tr class='<%= cycle('odd', 'even') -%>'>
<td><%= link_to role.name, admin_role_path(role) -%></td>
<td>
<%= link_to "Delete", admin_role_path(role), :method => :delete, :confirm => "Are you sure you want to delete this role?" -%>
</td>
</tr>
<% end -%>
</tbody>
</table>
@@ -17,6 +17,12 @@
# Initialize the Ansuz Plugin Manager instance
Ansuz::PluginManagerInstance = Ansuz::PluginManager.new

# authorization plugin
AUTHORIZATION_MIXIN = "object roles"
LOGIN_REQUIRED_REDIRECTION = { :controller => '/admin/account', :action => 'login' }
PERMISSION_DENIED_REDIRECTION = { :controller => '/page', :action => 'indexer', :path => '' }
STORE_LOCATION_METHOD = :store_location

Rails::Initializer.run do |config|
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
@@ -2,6 +2,7 @@

Ansuz::PluginManagerInstance.register_admin_menu_entry "Content", 'Manage Pages', '/admin/pages'

Ansuz::PluginManagerInstance.register_admin_menu_entry "Ansuz", 'Manage Roles', '/admin/roles'
Ansuz::PluginManagerInstance.register_admin_menu_entry "Ansuz", 'Site Settings', '/admin/site_settings'
Ansuz::PluginManagerInstance.register_admin_menu_entry "Ansuz", 'List Plugins', '/admin/plugins'
Ansuz::PluginManagerInstance.register_admin_menu_entry "Ansuz", 'Logout', '/admin/account/logout'
@@ -10,18 +10,21 @@
map.from_plugin :ansuz_scrollable_content
map.from_plugin :ansuz_testimonials

map.resources :users
map.resources :tags

# <admin routes>
map.namespace :admin do |admin|
admin.resources :pages, :member => [:shift_order], :has_one => [:page_metadata]
admin.resources :page_plugins
admin.resources :plugins
admin.resources :tags
admin.resources :roles
admin.resource :account
admin.connect 'account/:action/:id', :controller => 'account'
admin.resource :site_settings, :collection => [:fetch_theme_preview, :choose_theme]
admin.resources :tags
admin.connect 'account/:action/:id', :controller => 'account'
end
map.connect '/admin', :controller => 'admin/pages'
map.connect '/admin', :controller => 'admin/pages' # admin root
# </admin routes>

# stock rails routes
map.connect ':controller/:action/:id'
@@ -0,0 +1,21 @@
class CreateRoles < ActiveRecord::Migration

def self.up
create_table :roles_users, :id => false, :force => true do |t|
t.integer :user_id, :role_id
t.timestamps
end

create_table :roles, :force => true do |t|
t.string :name, :authorizable_type, :limit => 40
t.integer :authorizable_id
t.timestamps
end
end

def self.down
drop_table :roles
drop_table :roles_users
end

end
@@ -6,6 +6,8 @@ namespace :utils do
puts "Initial Admin User doesn't exist. Creating one with login: admin, password: admin, email: admin@example.com"
u = User.new :login => 'admin', :email => 'admin@example.com', :password => 'admin', :password_confirmation => 'admin'
u.save
u.has_role 'admin'
u.save
else
puts "Initial user already exists, exiting"
end
@@ -0,0 +1,5 @@
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
first:
id: 1
another:
id: 2
@@ -0,0 +1,10 @@
require File.dirname(__FILE__) + '/../test_helper'

class RoleTest < Test::Unit::TestCase
fixtures :roles

# Replace this with your real tests.
def test_truth
assert true
end
end
@@ -1,5 +1,6 @@
<%= title "Install Themes" -%>
<% content_for :sidebar do -%>
<%= link_to "Choose the theme for your site", '/admin/site_settings/choose_theme', :class => 'button icon edit' -%>
<div class='note'>
To install a theme, just click on it.<br /><br />

@@ -1,11 +1,12 @@
<% submit_text = "Create User" unless local_assigns.include?(:submit_text) -%>
<%= error_messages_for :user -%>
<table class='form-table'>
<%= form_row "Login", f.text_field(:login) %>
<%= form_row "Login", f.text_field(:login) %>
<%= form_row "Password", f.password_field(:password) %>
<%= form_row "Confirm Password", f.password_field(:password_confirmation) %>
<%= form_row "Email", f.text_field(:email) %>
<%= form_row "Admin?", f.check_box(:admin) %>
<%= form_row "Email", f.text_field(:email) %>
<%= form_row "Admin?", f.check_box(:admin) %>
<%= form_row "Roles", select_tag("roles[]", options_for_select(Role::STATIC_ROLES, @user.roles.map(&:name)), { :multiple => true, :size => 6 }), :note => "ctrl+click to select multiple." %>
</table>
<br />
<%= submit_tag submit_text -%> or <%= link_to "Cancel", admin_users_path -%>
@@ -0,0 +1,2 @@
.DS_STORE
.DS_Store
@@ -0,0 +1,170 @@
TO DO
+ Add Right model generator and DB-backed way of handling rights in addition to inlined "permit" checks
+ Added namespacing to @options instance variable to prevent possible name clashes
+ Add test generator instead of handling tests in test apps
+ Add support for groups
+ Extend grammar to allow "(admin or moderator or some_role) of some_model" (?) [Chris Hapgood]
+ Extend coverage to models. Look at Bruce Perens's ModelSecurity and access with_scope. (9/3006 - Recently investigated extension to model and the most programmer-friendly DSLs may require too much hacking on ActiveRecord.)


CHANGES (from most recent to oldest)


=== 1.0.10 release (February 27, 2008)

* Patch Series : Granular redirection configuration submitted by Thomas Weibel

WARNING : If you are upgrading from a previous install you may need
to change some configuration settings in your environment.rb file.

Remove DEFAULT_REDIRECTION_HASH config
Added granular LOGIN_REQUIRED_REDIRECTION hash or path config
Added granular PERMISSION_DENIED_REDIRECTION hash or path config
Added STORE_LOCATION_METHOD config
Support custom flash messages for each redirection type
Updated README.txt to provide instructions.
Enhanced support for integration with restful_authentication plugin.

=== 1.0.9 release (February 26, 2008)

* Patch #8571 : Add type argument to is_role_of_what submitted by Aslak Hellesøy (aslak_hellesoy)

In my RESTful index views for an AR type I often want to list all of the records *for a given type* for which the current
user has the role "show". (As opposed to getting *any* record for which the user has the role)

In order to achieve this, I have patched identity.rb so tht I can do this:

def index
if current_user.permit? 'admin'
# show all projects
@projects = Project.find(:all)
else
@projects = current_user.is_show_for_what(Project)
end
end

=== 1.0.8 release (February 26, 2008)

* Patch #11352 : Fixes a bug with role_regex and simple quoted roles submitted by 'a French RoR developer'

Documentation says:

<role> ::= /\w+/ | /'.*'/

But the next permission string isn't well parsed: " 'abcd:efgh' or 'abcd:ijkl' "
You get an error because the role_regex defined in parser.rb eats every simple quote between the first and the last
simple quote in the string.

So i patched the two instances of role_regex in parser.rb, from this:
role_regex = '\s*(\'\s*(.+)\s*\'|([A-Za-z]\w*))\s*'

to this (the question mark ends the first pattern as soon as possible, avoiding the inner simple quotes to be eaten):
role_regex = '\s*(\'\s*(.+?)\s*\'|([A-Za-z]\w*))\s*'

=== 1.0.7 release (February 25, 2008)

* Patch #9431 : Fixes a bug in identity.rb submitted by Michel Martens (blaumag)

If some authorizable instance accepts a role, then it responds true when queried for has_[role_name]?

Example:
country.has_kings? #=> false

user.has_role "king", country
country.has_kings? #=> true

user.has_no_role "king", country
country.has_kings? #=> true

The last time, country.has_kings? should be false.

=== 1.0.6 release (February 25, 2008)

* Patch #12170 : Additional HABTM options for acts_as_authorized_user
A very simple patch that allows options to be passed to the has_and_belogs_to_many relationship. This seems necessary
if the "User" object has a different name from the table name. has_and_belong_to_many does not automatically
use the table set by the "User" object so it must be specified (along with the foreign key if applicable).

Patch submitted by Eric Anderson (eric1234)

=== 1.0.5 release (February 25, 2008)

* Feature : Add additional test for current_user being set to the symbol ':false'.
This is for compatibility with the restful_authentication plugin which will
set current_user to :false on a bad login. Previously we were only testing
for current_user.nil? which was incomplete.

=== 1.0.4 release (February 25, 2008)

* Bugfix : RubyForge bug #9368. Problems with about.yml
Fixes a minor bug in the about.yml plugin metadata file
so that it will parse cleanly. [GR]

=== 1.0.3 release (February 17, 2008)

* Minor changes to USAGE text for ./script/generate role_model

=== 1.0.2 release (February 17, 2008)

* From this release forward the plugin requires use of Ruby on Rails version 2.x. Version 1.0.1 is the final release fully compatible with Rails 1.2.x.
* Upgraded the database migration generator to create the new Rails 2.0.x style 'sexy migrations'.

=== 1.0.1 release (February 17, 2008)

* Moved source code to public Git repository at GitHub.com (http://github.com/DocSavage/rails-authorization-plugin/tree/master)
* Removed attr_protected declaration from acts_as_authorized_user, acts_as_authorizable methods. These conflicted with usage of the Authorization plugin with models generated by the restful_authentication generator or any model that specified the safer attr_accessible whitelist. RA encourages the safer attr_accessible whitelisting of attributes that are accessible from its models. You cannot apply both attr_accessible and attr_protected in the same model. Users are encouraged to specify a whitelist of attr_accessible model attributes for their applications security. [grempe]

=== SVN

* Performance improvement for has_role? [Sean Geoghegan]

* Allow customization of message on redirection after failed authorization (:redirect_message option) [Joey Geiger]

* Patch to allow authorizable objects that use single table inheritance (STI) [Sean Geoghegan]

=== 1.0 release (Sept 13, 2006)

* Added attr_protected for habtm and has_many role ids to block security concern if developers use update_attributes(params[:auth_obj]) on an authorizable object [Michael Schuerig]

* Use before_filter rather than prepend_before_filter so necessary instance variables (and methods) can be established before trying authorization checks. This fix came about for Mephisto blog where a class-level permit "admin of site" was used. The site attribute was set in a before_filter. If you prepend your authorization filter, it will execute before any other before_filter, which is probably not a good idea.

* Add "about" yaml for future Rails plugin directory.

* Cleaned up exception handling a little [due to suggestion by Michael Schuerig]

* Add generator for role model and migration, e.g., "script/generate role_model Role".
Role model must be called "Role" at this time. More general naming as a TO DO.

* Removed simple_roles_table to simplify plugin.

* Moved all files in Authorization namespace into /publishare subdirectory
to reduce danger of clashes in load path [nod to Michael Schuerig].

* Small code refinement patch [Michael Schuerig]

* The colon preceding a model name in the authorization expression is now optional. The parser uses accepted prepositions to disambiguate models from roles.

* Change default parser from Recursive Descent parser to Eval parser.
Currently implemented recursive descent parser doesn't handle left-sided
boolean expressions well. Eval parser relies on Ruby (good thing), but
wherever there's an eval, we have to be more careful.

* Will start linking to and monitoring forum area at RubyForge
http://rubyforge.org/forum/?group_id=1797

* Added changelog :)

* Added return false to handle_redirection to short-circuit filters if
redirect occurs. This is second fix to prevent double renders.

* Changed the requires to pull files from the plugin directory. (Necessary for name conflicts between plugin and apps)

* Minor fixes to update documentation

=== 1.0 rc3 (July 19, 2006)

* Fix to prevent double redirect

* Fix to migration examples

... see svn log

0 comments on commit 46ecd79

Please sign in to comment.
You can’t perform that action at this time.