From 41b6a68d8d5f76f3bca9d7d178a25ac4865fa547 Mon Sep 17 00:00:00 2001 From: MoisesMachado Date: Fri, 14 Sep 2007 22:07:35 +0000 Subject: [PATCH] ActionItem5: initial implementation of rbac infrastructure to power access control --- app/controllers/role_controller.rb | 47 +++++++++++++++++++++++++++++++++++++++++++++++ app/helpers/application_helper.rb | 2 ++ app/helpers/role_helper.rb | 2 ++ app/models/person.rb | 6 ++++++ app/models/profile.rb | 2 ++ app/models/role.rb | 31 +++++++++++++++++++++++++++++++ app/models/role_assignment.rb | 9 +++++++++ app/views/role/_form.rhtml | 11 +++++++++++ app/views/role/index.rhtml | 10 ++++++++++ app/views/role/new.rhtml | 3 +++ config/routes.rb | 2 +- db/migrate/014_create_roles.rb | 12 ++++++++++++ db/migrate/015_create_role_assignments.rb | 14 ++++++++++++++ test/fixtures/role_assignments.yml | 5 +++++ test/fixtures/roles.yml | 5 +++++ test/functional/role_controller_test.rb | 18 ++++++++++++++++++ test/unit/role_assignment_test.rb | 10 ++++++++++ test/unit/role_test.rb | 10 ++++++++++ 18 files changed, 198 insertions(+), 1 deletion(-) create mode 100644 app/controllers/role_controller.rb create mode 100644 app/helpers/role_helper.rb create mode 100644 app/models/role.rb create mode 100644 app/models/role_assignment.rb create mode 100644 app/views/role/_form.rhtml create mode 100644 app/views/role/index.rhtml create mode 100644 app/views/role/new.rhtml create mode 100644 db/migrate/014_create_roles.rb create mode 100644 db/migrate/015_create_role_assignments.rb create mode 100644 test/fixtures/role_assignments.yml create mode 100644 test/fixtures/roles.yml create mode 100644 test/functional/role_controller_test.rb create mode 100644 test/unit/role_assignment_test.rb create mode 100644 test/unit/role_test.rb diff --git a/app/controllers/role_controller.rb b/app/controllers/role_controller.rb new file mode 100644 index 0000000..a50b423 --- /dev/null +++ b/app/controllers/role_controller.rb @@ -0,0 +1,47 @@ +class RoleController < ApplicationController + def index + @roles = Role.find(:all) + end + + def show + @role = Role.find(params[:id]) + end + + def new + @role = Role.new(:name => 'bla', :permissions => []) + end + + def create + role = Role.new(params[:role]) + if role.save + redirect_to :action => 'show', :id => role + else + flash[:notice] = _('Failed to create role') + redirect_to :action => 'index' + end + end + + def edit + @role = Role.find(params[:id]) + end + + def update + role = Role.find(params[:id]) + if role.update_attributes(params[:role]) + redirect_to :action => 'show', :id => role + else + flash[:notice] = _('Failed to edit role') + render :action => 'edit' + end + end + + def destroy + role = Role.find(params[:id]) + if role.destroy + redirect_to :action => 'index' + else + flash[:notice] = _('Failed to edit role') + redirect_to :action => 'index' + end + end +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 6a1fdfa..0a92b9b 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -167,6 +167,8 @@ module ApplicationHelper content_tag('div', content_tag('div', content_tag('label', label)) + html_for_field, :class => 'formfield') end + alias_method :labelled_form_field, :display_form_field + def labelled_form_for(name, object = nil, options = {}, &proc) object ||= instance_variable_get("@#{name}") form_for(name, object, { :builder => NoosferoFormBuilder }.merge(options), &proc) diff --git a/app/helpers/role_helper.rb b/app/helpers/role_helper.rb new file mode 100644 index 0000000..244d2a2 --- /dev/null +++ b/app/helpers/role_helper.rb @@ -0,0 +1,2 @@ +module RoleHelper +end diff --git a/app/models/person.rb b/app/models/person.rb index d3158fa..65757d1 100644 --- a/app/models/person.rb +++ b/app/models/person.rb @@ -14,6 +14,12 @@ class Person < Profile has_many :people, :through => :person_friendships, :foreign_key => 'friend_id' has_one :person_info + has_many :role_assignments + + def has_permission?(perm, res=nil) + role_assignments.any? {|ra| ra.has_permission?(perm, res)} + end + def info person_info end diff --git a/app/models/profile.rb b/app/models/profile.rb index 891e301..01820ed 100644 --- a/app/models/profile.rb +++ b/app/models/profile.rb @@ -35,6 +35,8 @@ class Profile < ActiveRecord::Base belongs_to :virtual_community has_many :affiliations, :dependent => :destroy has_many :people, :through => :affiliations + + has_many :role_assignment, :as => :resource # Sets the identifier for this profile. Raises an exception when called on a diff --git a/app/models/role.rb b/app/models/role.rb new file mode 100644 index 0000000..84d2fb3 --- /dev/null +++ b/app/models/role.rb @@ -0,0 +1,31 @@ +class Role < ActiveRecord::Base + + PERMISSIONS = { + :profile => { + 'edit_profile' => N_('Edit profile'), + 'post_content' => N_('Post content'), + 'destroy_profile' => N_('Destroy profile'), + }, + :system => { + } + } + + def self.permission_name(p) +# msgid = ... +# gettext(msgid) + raise "Moises need to write me" + end + + has_many :role_assignments + + serialize :permissions, Array + + def initialize(*args) + super(*args) + permissions = [] + end + + def has_permission?(perm) + permissions.include?(perm) + end +end diff --git a/app/models/role_assignment.rb b/app/models/role_assignment.rb new file mode 100644 index 0000000..aa02c58 --- /dev/null +++ b/app/models/role_assignment.rb @@ -0,0 +1,9 @@ +class RoleAssignment < ActiveRecord::Base + belongs_to :role + belongs_to :person + belongs_to :resource, :polymorphic => true + + def has_permission?(perm, res) + role.has_permission?(perm) && (resource == res) + end +end diff --git a/app/views/role/_form.rhtml b/app/views/role/_form.rhtml new file mode 100644 index 0000000..1ed5c67 --- /dev/null +++ b/app/views/role/_form.rhtml @@ -0,0 +1,11 @@ +<%= error_messages_for :role %> + +<% labelled_form_for :role, @role do |f| %> + + <%= f.text_field :name %> + + <%= _('Permissions: ') %>
+ <% Role::PERMISSIONS[:profile].keys.each do |p| %> + <%= labelled_form_field("bla", (check_box_tag "role[permissions][#{p}]", @role.has_permission?(p))) %> + <% end %> +<% end %> diff --git a/app/views/role/index.rhtml b/app/views/role/index.rhtml new file mode 100644 index 0000000..d358fe2 --- /dev/null +++ b/app/views/role/index.rhtml @@ -0,0 +1,10 @@ +<%= link_to _('New role'), :action => 'new' %> + diff --git a/app/views/role/new.rhtml b/app/views/role/new.rhtml new file mode 100644 index 0000000..2497ce5 --- /dev/null +++ b/app/views/role/new.rhtml @@ -0,0 +1,3 @@ +

<%= _('New Role') %>

+ +<%= render :partial => 'form', :locals => { :mode => :new } %> diff --git a/config/routes.rb b/config/routes.rb index 50a06c1..5769f87 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -33,7 +33,7 @@ ActionController::Routing::Routes.draw do |map| ###################################################### # administrative tasks for a virtual community map.admin 'admin', :controller => 'admin_panel' - map.admin 'admin/:controller/:action/:id', :controller => /(admin_panel|features|manage_tags|edit_template)/ + map.admin 'admin/:controller/:action/:id', :controller => /(admin_panel|features|manage_tags|edit_template|role)/ ###################################################### ## Controllers that are used by system admin diff --git a/db/migrate/014_create_roles.rb b/db/migrate/014_create_roles.rb new file mode 100644 index 0000000..9553dfe --- /dev/null +++ b/db/migrate/014_create_roles.rb @@ -0,0 +1,12 @@ +class CreateRoles < ActiveRecord::Migration + def self.up + create_table :roles do |t| + t.column :name, :string + t.column :permissions, :string + end + end + + def self.down + drop_table :roles + end +end diff --git a/db/migrate/015_create_role_assignments.rb b/db/migrate/015_create_role_assignments.rb new file mode 100644 index 0000000..f2112b7 --- /dev/null +++ b/db/migrate/015_create_role_assignments.rb @@ -0,0 +1,14 @@ +class CreateRoleAssignments < ActiveRecord::Migration + def self.up + create_table :role_assignments do |t| + t.column :person_id, :integer + t.column :role_id, :integer + t.column :resource_id, :integer + t.column :resource_type, :string + end + end + + def self.down + drop_table :role_assignments + end +end diff --git a/test/fixtures/role_assignments.yml b/test/fixtures/role_assignments.yml new file mode 100644 index 0000000..b49c4eb --- /dev/null +++ b/test/fixtures/role_assignments.yml @@ -0,0 +1,5 @@ +# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html +one: + id: 1 +two: + id: 2 diff --git a/test/fixtures/roles.yml b/test/fixtures/roles.yml new file mode 100644 index 0000000..b49c4eb --- /dev/null +++ b/test/fixtures/roles.yml @@ -0,0 +1,5 @@ +# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html +one: + id: 1 +two: + id: 2 diff --git a/test/functional/role_controller_test.rb b/test/functional/role_controller_test.rb new file mode 100644 index 0000000..b79b515 --- /dev/null +++ b/test/functional/role_controller_test.rb @@ -0,0 +1,18 @@ +require File.dirname(__FILE__) + '/../test_helper' +require 'role_controller' + +# Re-raise errors caught by the controller. +class RoleController; def rescue_action(e) raise e end; end + +class RoleControllerTest < Test::Unit::TestCase + def setup + @controller = RoleController.new + @request = ActionController::TestRequest.new + @response = ActionController::TestResponse.new + end + + # Replace this with your real tests. + def test_truth + assert true + end +end diff --git a/test/unit/role_assignment_test.rb b/test/unit/role_assignment_test.rb new file mode 100644 index 0000000..ea1da5e --- /dev/null +++ b/test/unit/role_assignment_test.rb @@ -0,0 +1,10 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class RoleAssignmentTest < Test::Unit::TestCase + fixtures :role_assignments + + # Replace this with your real tests. + def test_truth + assert true + end +end diff --git a/test/unit/role_test.rb b/test/unit/role_test.rb new file mode 100644 index 0000000..05d6652 --- /dev/null +++ b/test/unit/role_test.rb @@ -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 -- libgit2 0.21.2