Commit 41b6a68d8d5f76f3bca9d7d178a25ac4865fa547

Authored by MoisesMachado
1 parent a6ca4493

ActionItem5: initial implementation of rbac infrastructure to power access control


git-svn-id: https://svn.colivre.coop.br/svn/noosfero/trunk@481 3f533792-8f58-4932-b0fe-aaf55b0a4547
app/controllers/role_controller.rb 0 → 100644
... ... @@ -0,0 +1,47 @@
  1 +class RoleController < ApplicationController
  2 + def index
  3 + @roles = Role.find(:all)
  4 + end
  5 +
  6 + def show
  7 + @role = Role.find(params[:id])
  8 + end
  9 +
  10 + def new
  11 + @role = Role.new(:name => 'bla', :permissions => [])
  12 + end
  13 +
  14 + def create
  15 + role = Role.new(params[:role])
  16 + if role.save
  17 + redirect_to :action => 'show', :id => role
  18 + else
  19 + flash[:notice] = _('Failed to create role')
  20 + redirect_to :action => 'index'
  21 + end
  22 + end
  23 +
  24 + def edit
  25 + @role = Role.find(params[:id])
  26 + end
  27 +
  28 + def update
  29 + role = Role.find(params[:id])
  30 + if role.update_attributes(params[:role])
  31 + redirect_to :action => 'show', :id => role
  32 + else
  33 + flash[:notice] = _('Failed to edit role')
  34 + render :action => 'edit'
  35 + end
  36 + end
  37 +
  38 + def destroy
  39 + role = Role.find(params[:id])
  40 + if role.destroy
  41 + redirect_to :action => 'index'
  42 + else
  43 + flash[:notice] = _('Failed to edit role')
  44 + redirect_to :action => 'index'
  45 + end
  46 + end
  47 +end
... ...
app/helpers/application_helper.rb
... ... @@ -167,6 +167,8 @@ module ApplicationHelper
167 167 content_tag('div', content_tag('div', content_tag('label', label)) + html_for_field, :class => 'formfield')
168 168 end
169 169  
  170 + alias_method :labelled_form_field, :display_form_field
  171 +
170 172 def labelled_form_for(name, object = nil, options = {}, &proc)
171 173 object ||= instance_variable_get("@#{name}")
172 174 form_for(name, object, { :builder => NoosferoFormBuilder }.merge(options), &proc)
... ...
app/helpers/role_helper.rb 0 → 100644
... ... @@ -0,0 +1,2 @@
  1 +module RoleHelper
  2 +end
... ...
app/models/person.rb
... ... @@ -14,6 +14,12 @@ class Person &lt; Profile
14 14 has_many :people, :through => :person_friendships, :foreign_key => 'friend_id'
15 15 has_one :person_info
16 16  
  17 + has_many :role_assignments
  18 +
  19 + def has_permission?(perm, res=nil)
  20 + role_assignments.any? {|ra| ra.has_permission?(perm, res)}
  21 + end
  22 +
17 23 def info
18 24 person_info
19 25 end
... ...
app/models/profile.rb
... ... @@ -35,6 +35,8 @@ class Profile &lt; ActiveRecord::Base
35 35 belongs_to :virtual_community
36 36 has_many :affiliations, :dependent => :destroy
37 37 has_many :people, :through => :affiliations
  38 +
  39 + has_many :role_assignment, :as => :resource
38 40  
39 41  
40 42 # Sets the identifier for this profile. Raises an exception when called on a
... ...
app/models/role.rb 0 → 100644
... ... @@ -0,0 +1,31 @@
  1 +class Role < ActiveRecord::Base
  2 +
  3 + PERMISSIONS = {
  4 + :profile => {
  5 + 'edit_profile' => N_('Edit profile'),
  6 + 'post_content' => N_('Post content'),
  7 + 'destroy_profile' => N_('Destroy profile'),
  8 + },
  9 + :system => {
  10 + }
  11 + }
  12 +
  13 + def self.permission_name(p)
  14 +# msgid = ...
  15 +# gettext(msgid)
  16 + raise "Moises need to write me"
  17 + end
  18 +
  19 + has_many :role_assignments
  20 +
  21 + serialize :permissions, Array
  22 +
  23 + def initialize(*args)
  24 + super(*args)
  25 + permissions = []
  26 + end
  27 +
  28 + def has_permission?(perm)
  29 + permissions.include?(perm)
  30 + end
  31 +end
... ...
app/models/role_assignment.rb 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +class RoleAssignment < ActiveRecord::Base
  2 + belongs_to :role
  3 + belongs_to :person
  4 + belongs_to :resource, :polymorphic => true
  5 +
  6 + def has_permission?(perm, res)
  7 + role.has_permission?(perm) && (resource == res)
  8 + end
  9 +end
... ...
app/views/role/_form.rhtml 0 → 100644
... ... @@ -0,0 +1,11 @@
  1 +<%= error_messages_for :role %>
  2 +
  3 +<% labelled_form_for :role, @role do |f| %>
  4 +
  5 + <%= f.text_field :name %>
  6 +
  7 + <%= _('Permissions: ') %> <br>
  8 + <% Role::PERMISSIONS[:profile].keys.each do |p| %>
  9 + <%= labelled_form_field("bla", (check_box_tag "role[permissions][#{p}]", @role.has_permission?(p))) %>
  10 + <% end %>
  11 +<% end %>
... ...
app/views/role/index.rhtml 0 → 100644
... ... @@ -0,0 +1,10 @@
  1 +<%= link_to _('New role'), :action => 'new' %>
  2 +<ul>
  3 + <% @roles.each do |role| %>
  4 + <li>
  5 + <%= link_to role.name, :action => 'show', :id => role %>
  6 + <%= link_to _('Edit'), :action => 'edit', :id => role %>
  7 + <%= link_to _('Destroy'), :action => 'destoy', :id => role %>
  8 + </li>
  9 + <% end %>
  10 +</ul>
... ...
app/views/role/new.rhtml 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +<h2> <%= _('New Role') %> </h2>
  2 +
  3 +<%= render :partial => 'form', :locals => { :mode => :new } %>
... ...
config/routes.rb
... ... @@ -33,7 +33,7 @@ ActionController::Routing::Routes.draw do |map|
33 33 ######################################################
34 34 # administrative tasks for a virtual community
35 35 map.admin 'admin', :controller => 'admin_panel'
36   - map.admin 'admin/:controller/:action/:id', :controller => /(admin_panel|features|manage_tags|edit_template)/
  36 + map.admin 'admin/:controller/:action/:id', :controller => /(admin_panel|features|manage_tags|edit_template|role)/
37 37  
38 38 ######################################################
39 39 ## Controllers that are used by system admin
... ...
db/migrate/014_create_roles.rb 0 → 100644
... ... @@ -0,0 +1,12 @@
  1 +class CreateRoles < ActiveRecord::Migration
  2 + def self.up
  3 + create_table :roles do |t|
  4 + t.column :name, :string
  5 + t.column :permissions, :string
  6 + end
  7 + end
  8 +
  9 + def self.down
  10 + drop_table :roles
  11 + end
  12 +end
... ...
db/migrate/015_create_role_assignments.rb 0 → 100644
... ... @@ -0,0 +1,14 @@
  1 +class CreateRoleAssignments < ActiveRecord::Migration
  2 + def self.up
  3 + create_table :role_assignments do |t|
  4 + t.column :person_id, :integer
  5 + t.column :role_id, :integer
  6 + t.column :resource_id, :integer
  7 + t.column :resource_type, :string
  8 + end
  9 + end
  10 +
  11 + def self.down
  12 + drop_table :role_assignments
  13 + end
  14 +end
... ...
test/fixtures/role_assignments.yml 0 → 100644
... ... @@ -0,0 +1,5 @@
  1 +# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
  2 +one:
  3 + id: 1
  4 +two:
  5 + id: 2
... ...
test/fixtures/roles.yml 0 → 100644
... ... @@ -0,0 +1,5 @@
  1 +# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
  2 +one:
  3 + id: 1
  4 +two:
  5 + id: 2
... ...
test/functional/role_controller_test.rb 0 → 100644
... ... @@ -0,0 +1,18 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +require 'role_controller'
  3 +
  4 +# Re-raise errors caught by the controller.
  5 +class RoleController; def rescue_action(e) raise e end; end
  6 +
  7 +class RoleControllerTest < Test::Unit::TestCase
  8 + def setup
  9 + @controller = RoleController.new
  10 + @request = ActionController::TestRequest.new
  11 + @response = ActionController::TestResponse.new
  12 + end
  13 +
  14 + # Replace this with your real tests.
  15 + def test_truth
  16 + assert true
  17 + end
  18 +end
... ...
test/unit/role_assignment_test.rb 0 → 100644
... ... @@ -0,0 +1,10 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class RoleAssignmentTest < Test::Unit::TestCase
  4 + fixtures :role_assignments
  5 +
  6 + # Replace this with your real tests.
  7 + def test_truth
  8 + assert true
  9 + end
  10 +end
... ...
test/unit/role_test.rb 0 → 100644
... ... @@ -0,0 +1,10 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class RoleTest < Test::Unit::TestCase
  4 + fixtures :roles
  5 +
  6 + # Replace this with your real tests.
  7 + def test_truth
  8 + assert true
  9 + end
  10 +end
... ...