radiant-rbac_base-extension 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. data/.gitignore +1 -0
  2. data/HELP_developer.md +18 -0
  3. data/README.markdown +30 -0
  4. data/Rakefile +137 -0
  5. data/VERSION +1 -0
  6. data/app/controllers/admin/roles_controller.rb +91 -0
  7. data/app/helpers/admin/alterations_helper.rb +9 -0
  8. data/app/helpers/admin/roles_helper.rb +5 -0
  9. data/app/models/role.rb +33 -0
  10. data/app/models/role_action_observer.rb +13 -0
  11. data/app/models/role_user.rb +2 -0
  12. data/app/views/admin/roles/_add_role_form.html.haml +4 -0
  13. data/app/views/admin/roles/index.html.haml +30 -0
  14. data/app/views/admin/roles/show.html.haml +29 -0
  15. data/app/views/admin/users/preferences.html.haml +34 -0
  16. data/config/locales/en.yml +3 -0
  17. data/config/routes.rb +8 -0
  18. data/cucumber.yml +1 -0
  19. data/db/migrate/001_create_roles.rb +11 -0
  20. data/db/migrate/002_create_role_users.rb +16 -0
  21. data/db/migrate/003_setup_standard_roles.rb +29 -0
  22. data/db/migrate/004_alter_roles.rb +10 -0
  23. data/db/migrate/005_add_standard_role_details.rb +20 -0
  24. data/db/migrate/006_add_user_info.rb +10 -0
  25. data/db/migrate/20100705182511_rename_role_developer_to_designer.rb +13 -0
  26. data/features/support/env.rb +16 -0
  27. data/features/support/paths.rb +14 -0
  28. data/lib/rbac_support.rb +19 -0
  29. data/lib/tasks/rbac_base_extension_tasks.rake +55 -0
  30. data/public/javascripts/rbac/admin/role_details.js +162 -0
  31. data/public/stylesheets/rbac/rbac.css +20 -0
  32. data/radiant-rbac_base-extension.gemspec +91 -0
  33. data/rbac_base_extension.rb +28 -0
  34. data/spec/controllers/admin/roles_controller_spec.rb +142 -0
  35. data/spec/controllers/admin/roles_routing_spec.rb +27 -0
  36. data/spec/helpers/admin/roles_helper_spec.rb +12 -0
  37. data/spec/models/role_spec.rb +82 -0
  38. data/spec/models/user_spec.rb +9 -0
  39. data/spec/spec.opts +6 -0
  40. data/spec/spec_helper.rb +36 -0
  41. data/spec/views/admin/roles/index_spec.rb +17 -0
  42. data/spec/views/admin/roles/show_spec.rb +14 -0
  43. metadata +129 -0
@@ -0,0 +1,3 @@
1
+ ---
2
+ en:
3
+ rbac base: Rbac Base
@@ -0,0 +1,8 @@
1
+ ActionController::Routing::Routes.draw do |map|
2
+ map.namespace :admin do |admin|
3
+ admin.resources :roles#, :member => {:users => :get, :remove_user => :delete, :add_user => :post}
4
+ admin.role_user '/roles/:role_id/users/:id', :controller => 'roles', :action => 'remove_user', :conditions => {:method => :delete}
5
+ admin.role_user '/roles/:role_id/users/:id', :controller => 'roles', :action => 'add_user', :conditions => {:method => :post}
6
+ admin.role_users '/roles/:role_id/users', :controller => 'roles', :action => 'users', :conditions => {:method => :get}
7
+ end
8
+ end
@@ -0,0 +1 @@
1
+ default: --format progress features --tags ~@proposed,~@in_progress
@@ -0,0 +1,11 @@
1
+ class CreateRoles < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :roles do |t|
4
+ t.column :role_name, :string, :limit => 64, :default => "New Role"
5
+ end
6
+ end
7
+
8
+ def self.down
9
+ drop_table :roles
10
+ end
11
+ end
@@ -0,0 +1,16 @@
1
+ class CreateRoleUsers < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :roles_users, :id => false do |t|
4
+ t.column :role_id, :integer, :null => false
5
+ t.column :user_id, :integer, :null => false
6
+ end
7
+ add_index :roles_users, :role_id
8
+ add_index :roles_users, :user_id
9
+ end
10
+
11
+ def self.down
12
+ remove_index :roles_users, :user_id
13
+ remove_index :roles_users, :role_id
14
+ drop_table :roles_users
15
+ end
16
+ end
@@ -0,0 +1,29 @@
1
+ class SetupStandardRoles < ActiveRecord::Migration
2
+ def self.up
3
+ User.send :has_and_belongs_to_many, :roles
4
+ self.setup_admins
5
+ self.setup_designers
6
+ end
7
+ def self.down
8
+ say("Removing all Roles.")
9
+ Role.find(:all, :conditions => ["role_name = ? OR role_name = ?",'Admin','Designer']).map(&:destroy)
10
+ end
11
+
12
+ def self.setup_admins
13
+ admin_users = User.find_all_by_admin(true)
14
+ admin_role = Role.create!(:role_name => 'Admin')
15
+ admin_users.each do |user|
16
+ say("Adding #{user.login} to the #{admin_role.role_name} role.")
17
+ user.roles << admin_role
18
+ end
19
+ end
20
+
21
+ def self.setup_designers
22
+ designer_users = User.find_all_by_designer(true)
23
+ designer_role = Role.create!(:role_name => 'Designer')
24
+ designer_users.each do |user|
25
+ say("Adding #{user.name} to the #{designer_role.role_name} role.")
26
+ user.roles << designer_role
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,10 @@
1
+ class AlterRoles < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :roles, :description, :string
4
+ add_column :roles, :allow_empty, :boolean, :default => true
5
+ end
6
+ def self.down
7
+ remove_column :roles, :allow_empty
8
+ remove_column :roles, :description
9
+ end
10
+ end
@@ -0,0 +1,20 @@
1
+ class AddStandardRoleDetails < ActiveRecord::Migration
2
+ def self.up
3
+ Role.find(:all).each do |role|
4
+ if role.role_name == 'Admin'
5
+ say("Adding Admin description.")
6
+ role.update_attributes({:allow_empty => false,
7
+ :description => %{Users in the Admin role, by default, have access to all features of the system.}})
8
+ elsif role.role_name == 'Designer'
9
+ say("Adding Designer description.")
10
+ role.update_attributes({:allow_empty => true,
11
+ :description => %{Users in the Designer role, by default, have access to all features of the system except user management.}})
12
+ else
13
+ role.update_attribute(:allow_empty, true)
14
+ end
15
+ end
16
+ end
17
+ def self.down
18
+ # no need
19
+ end
20
+ end
@@ -0,0 +1,10 @@
1
+ class AddUserInfo < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :roles, :created_by_id, :integer
4
+ add_column :roles, :updated_by_id, :integer
5
+ end
6
+ def self.down
7
+ remove_column :roles, :updated_by_id
8
+ remove_column :roles, :created_by_id
9
+ end
10
+ end
@@ -0,0 +1,13 @@
1
+ class RenameRoleDeveloperToDesigner < ActiveRecord::Migration
2
+ def self.up
3
+ if role = Role.find_by_role_name('Developer')
4
+ role.update_attribute(:role_name, 'Designer')
5
+ end
6
+ end
7
+
8
+ def self.down
9
+ if role = Role.find_by_role_name('Designer')
10
+ role.update_attribute(:role_name, 'Developer')
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,16 @@
1
+ # Sets up the Rails environment for Cucumber
2
+ ENV["RAILS_ENV"] = "test"
3
+ # Extension root
4
+ extension_env = File.expand_path(File.dirname(__FILE__) + '/../../../../../config/environment')
5
+ require extension_env+'.rb'
6
+
7
+ Dir.glob(File.join(RADIANT_ROOT, "features", "**", "*.rb")).each {|step| require step}
8
+
9
+ Cucumber::Rails::World.class_eval do
10
+ include Dataset
11
+ datasets_directory "#{RADIANT_ROOT}/spec/datasets"
12
+ Dataset::Resolver.default = Dataset::DirectoryResolver.new("#{RADIANT_ROOT}/spec/datasets", File.dirname(__FILE__) + '/../../spec/datasets', File.dirname(__FILE__) + '/../datasets')
13
+ self.datasets_database_dump_path = "#{Rails.root}/tmp/dataset"
14
+
15
+ # dataset :rbac_base
16
+ end
@@ -0,0 +1,14 @@
1
+ def path_to(page_name)
2
+ case page_name
3
+
4
+ when /the homepage/i
5
+ root_path
6
+
7
+ when /login/i
8
+ login_path
9
+ # Add more page name => path mappings here
10
+
11
+ else
12
+ raise "Can't find mapping from \"#{page_name}\" to a path."
13
+ end
14
+ end
@@ -0,0 +1,19 @@
1
+ module RbacSupport
2
+
3
+ all_roles = Role.find(:all)
4
+
5
+ all_roles.each do | possible_role |
6
+ define_method("#{possible_role.role_name.underscore}?") do
7
+ if @my_roles == nil
8
+ @my_roles = Hash.new
9
+ roles.each do | role |
10
+ @my_roles["#{role.role_name.underscore}"] = true
11
+ end
12
+ end
13
+ if Radiant::Config['roles.admin.sees_everything'] == 'true' && possible_role.role_name.downcase != 'admin'
14
+ return true if admin?
15
+ end
16
+ @my_roles["#{possible_role.role_name.underscore}"] #|| self[:admin] == true
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,55 @@
1
+ namespace :radiant do
2
+ namespace :extensions do
3
+ namespace :rbac_base do
4
+
5
+ desc "Runs the migration of the Rbac Base extension"
6
+ task :migrate => :environment do
7
+ require 'radiant/extension_migrator'
8
+ if ENV["VERSION"]
9
+ RbacBaseExtension.migrator.migrate(ENV["VERSION"].to_i)
10
+ Rake::Task['db:schema:dump'].invoke
11
+ else
12
+ RbacBaseExtension.migrator.migrate
13
+ Rake::Task['db:schema:dump'].invoke
14
+ end
15
+ end
16
+
17
+ desc "Copies public assets of the Rbac Base to the instance public/ directory."
18
+ task :update => :environment do
19
+ is_svn_or_dir = proc {|path| path =~ /\.svn/ || File.directory?(path) }
20
+ puts "Copying assets from RbacBaseExtension"
21
+ Dir[RbacBaseExtension.root + "/public/**/*"].reject(&is_svn_or_dir).each do |file|
22
+ path = file.sub(RbacBaseExtension.root, '')
23
+ directory = File.dirname(path)
24
+ mkdir_p RAILS_ROOT + directory, :verbose => false
25
+ cp file, RAILS_ROOT + path, :verbose => false
26
+ end
27
+ unless RbacBaseExtension.root.starts_with? RAILS_ROOT # don't need to copy vendored tasks
28
+ puts "Copying rake tasks from RbacBaseExtension"
29
+ local_tasks_path = File.join(RAILS_ROOT, %w(lib tasks))
30
+ mkdir_p local_tasks_path, :verbose => false
31
+ Dir[File.join RbacBaseExtension.root, %w(lib tasks *.rake)].each do |file|
32
+ cp file, local_tasks_path, :verbose => false
33
+ end
34
+ end
35
+ end
36
+
37
+ desc "Syncs all available translations for this ext to the English ext master"
38
+ task :sync => :environment do
39
+ # The main translation root, basically where English is kept
40
+ language_root = RbacBaseExtension.root + "/config/locales"
41
+ words = TranslationSupport.get_translation_keys(language_root)
42
+
43
+ Dir["#{language_root}/*.yml"].each do |filename|
44
+ next if filename.match('_available_tags')
45
+ basename = File.basename(filename, '.yml')
46
+ puts "Syncing #{basename}"
47
+ (comments, other) = TranslationSupport.read_file(filename, basename)
48
+ words.each { |k,v| other[k] ||= words[k] } # Initializing hash variable as empty if it does not exist
49
+ other.delete_if { |k,v| !words[k] } # Remove if not defined in en.yml
50
+ TranslationSupport.write_file(filename, basename, comments, other)
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,162 @@
1
+ function RoleManager() {
2
+ var role_id = "";
3
+ var available = null;
4
+ var taken = null;
5
+ var drag_refs = new Object();
6
+ }
7
+
8
+ var spinners = {
9
+ show: function(){
10
+ $('busy_taken', 'busy_available').invoke('show');
11
+ },
12
+ hide: function(){
13
+ $('busy_taken', 'busy_available').invoke('hide');
14
+ }
15
+ }
16
+
17
+ RoleManager.prototype.updateDraggables = function() {
18
+ try {
19
+ if(this.drag_refs == undefined || this.drag_refs == NULL) {
20
+ this.drag_refs = new Object();
21
+ }
22
+
23
+ this.available.each(function(e) {
24
+ var my_draggable = new Draggable("user_" + e[0], {constraint: 'vertical', revert: true} );
25
+ manager.drag_refs["user_" + e[0]] = my_draggable;
26
+ });
27
+ this.taken.each(function(e) {
28
+ var my_draggable = new Draggable("user_" + e[0], {constraint: 'vertical', revert: true} );
29
+ manager.drag_refs["user_" + e[0]] = my_draggable;
30
+ });
31
+ } catch(e) {
32
+ alert("An exception occured while making the users draggable: " + e.description);
33
+ }
34
+ }
35
+
36
+ RoleManager.prototype.updateData = function(data) {
37
+ data.available.each(function(e) {
38
+ new Insertion.Bottom('available_users', "<li class='user' id='user_" + e[0] + "' value='" + e[0] + "'>" + e[1] + "</li>");
39
+ });
40
+
41
+ data.taken.each(function(e) {
42
+ new Insertion.Bottom('taken_users', "<li class='user' id='user_" + e[0] + "' value='" + e[0] + "'>" + e[1] + "</li>");
43
+ });
44
+
45
+ this.available = data.available;
46
+ this.taken = data.taken;
47
+ }
48
+
49
+ RoleManager.prototype.addUser = function(element) {
50
+ user_id = element.readAttribute("value");
51
+ new Ajax.Request("/admin/roles/"+role_id+"/users/"+user_id, {
52
+ method: 'post',
53
+ onCreate: function(){
54
+ spinners.show();
55
+ },
56
+ onSuccess: function(transport) {
57
+ var response = transport.responseText.evalJSON();
58
+ var _id = "user_" + response.user_id;
59
+ if(response.status == "Ok") {
60
+ var element = $(_id)
61
+ var _value = response.user_id
62
+ var _text = element.innerHTML;
63
+
64
+ element.toggle();
65
+ manager.drag_refs[_id].destroy();
66
+ element.remove();
67
+ new Insertion.Bottom('taken_users', "<li class='user' id='" + _id +
68
+ "' value='" + _value + "'>" + _text + "</li>");
69
+ manager.drag_refs[_id] = new Draggable(_id);
70
+ } else {
71
+ alert("There was a problem adding the user to this role.");
72
+ manager.drag_refs[_id].destroy();
73
+ manager.drag_refs[_id] = new Draggable(_id);
74
+ }
75
+ spinners.hide();
76
+ },
77
+ onFailure: function(transport) {
78
+ alert("There was a problem adding the user to this role.");
79
+ spinners.hide();
80
+ }
81
+ });
82
+ }
83
+
84
+ RoleManager.prototype.removeUser = function(element) {
85
+ user_id = element.readAttribute("value");
86
+ new Ajax.Request("/admin/roles/"+role_id+"/users/"+user_id, {
87
+ method: 'delete',
88
+ onCreate: function() {
89
+ spinners.show();
90
+ },
91
+ onSuccess: function(transport) {
92
+ var response = transport.responseText.evalJSON();
93
+ var _id = "user_" + response.user_id;
94
+ if(response.status == "Ok") {
95
+ var element = $(_id)
96
+ var _value = response.user_id
97
+ var _text = element.innerHTML;
98
+
99
+ element.toggle();
100
+ manager.drag_refs[_id].destroy();
101
+ element.remove();
102
+ new Insertion.Bottom('available_users', "<li class='user' id='" + _id +
103
+ "' value='" + _value + "'>" + _text + "</li>");
104
+ manager.drag_refs[_id] = new Draggable(_id);
105
+ } else {
106
+ alert("There was a problem removing the user from this role.");
107
+ manager.drag_refs[_id].destroy();
108
+ manager.drag_refs[_id] = new Draggable(_id);
109
+ }
110
+ spinners.hide();
111
+ },
112
+ onFailure: function(transport) {
113
+ alert("There was a problem removing the user from this role.");
114
+ spinners.hide();
115
+ }
116
+ })
117
+ }
118
+
119
+ RoleManager.prototype.loadData = function(role_id) {
120
+ new Ajax.Request('/admin/roles/'+role_id+'/users', {
121
+ method: 'get',
122
+ contentType: 'application/javascript',
123
+ onCreate: function(){
124
+ spinners.show();
125
+ },
126
+ onFailure: function(transport) {
127
+ alert('There was a problem with the script');
128
+ spinners.hide();
129
+ },
130
+ onSuccess: function(transport) {
131
+ try {
132
+ var val = transport.responseText.evalJSON();
133
+ manager.updateData(val);
134
+ new PeriodicalExecuter(function(pe) { manager.updateDraggables(); pe.stop(); }, 0.1);
135
+ Droppables.add('available_users', {
136
+ accept: "user",
137
+ hoverclass: "hover",
138
+ onDrop: function(element) {
139
+ manager.removeUser(element);
140
+ }
141
+ });
142
+ Droppables.add('taken_users', {
143
+ accept: "user",
144
+ hoverclass: "hover",
145
+ onDrop: function(element) {
146
+ manager.addUser(element);
147
+ }
148
+ });
149
+ spinners.hide();
150
+ } catch(e) {
151
+ alert("Exception occured in json code: " + e);
152
+ spinners.hide();
153
+ }
154
+ }
155
+ });
156
+ }
157
+
158
+ var manager = new RoleManager();
159
+
160
+ Event.observe(window, 'load', function() {
161
+ manager.loadData(role_id);
162
+ });
@@ -0,0 +1,20 @@
1
+ .UserList {
2
+ background: #fff;
3
+ color: #000;
4
+ list-style: none;
5
+ margin: 0 0 1em;
6
+ min-height: 1em;
7
+ padding: 10px 0;
8
+ }
9
+ .UserList.hover {
10
+ background: #efe;
11
+ }
12
+ .UserList li {
13
+ line-height: 1.2em;
14
+ list-style: none;
15
+ margin: 0;
16
+ padding: 2px 2px 2px 25px;
17
+ }
18
+ .rbac_busy_marker {
19
+ position: absolute;
20
+ }
@@ -0,0 +1,91 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{radiant-rbac_base-extension}
8
+ s.version = "1.3.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Jim Gay"]
12
+ s.date = %q{2010-07-05}
13
+ s.description = %q{Flexible user role management for Radiant.}
14
+ s.email = %q{jim@saturnflyer.com}
15
+ s.extra_rdoc_files = [
16
+ "README.markdown"
17
+ ]
18
+ s.files = [
19
+ ".gitignore",
20
+ "HELP_developer.md",
21
+ "README.markdown",
22
+ "Rakefile",
23
+ "VERSION",
24
+ "app/controllers/admin/roles_controller.rb",
25
+ "app/helpers/admin/alterations_helper.rb",
26
+ "app/helpers/admin/roles_helper.rb",
27
+ "app/models/role.rb",
28
+ "app/models/role_action_observer.rb",
29
+ "app/models/role_user.rb",
30
+ "app/views/admin/roles/_add_role_form.html.haml",
31
+ "app/views/admin/roles/index.html.haml",
32
+ "app/views/admin/roles/show.html.haml",
33
+ "app/views/admin/users/preferences.html.haml",
34
+ "config/locales/en.yml",
35
+ "config/routes.rb",
36
+ "cucumber.yml",
37
+ "db/migrate/001_create_roles.rb",
38
+ "db/migrate/002_create_role_users.rb",
39
+ "db/migrate/003_setup_standard_roles.rb",
40
+ "db/migrate/004_alter_roles.rb",
41
+ "db/migrate/005_add_standard_role_details.rb",
42
+ "db/migrate/006_add_user_info.rb",
43
+ "db/migrate/20100705182511_rename_role_developer_to_designer.rb",
44
+ "features/support/env.rb",
45
+ "features/support/paths.rb",
46
+ "lib/rbac_support.rb",
47
+ "lib/tasks/rbac_base_extension_tasks.rake",
48
+ "public/javascripts/rbac/admin/role_details.js",
49
+ "public/stylesheets/rbac/rbac.css",
50
+ "radiant-rbac_base-extension.gemspec",
51
+ "rbac_base_extension.rb",
52
+ "spec/controllers/admin/roles_controller_spec.rb",
53
+ "spec/controllers/admin/roles_routing_spec.rb",
54
+ "spec/helpers/admin/roles_helper_spec.rb",
55
+ "spec/models/role_spec.rb",
56
+ "spec/models/user_spec.rb",
57
+ "spec/spec.opts",
58
+ "spec/spec_helper.rb",
59
+ "spec/views/admin/roles/index_spec.rb",
60
+ "spec/views/admin/roles/show_spec.rb"
61
+ ]
62
+ s.homepage = %q{http://github.com/saturnflyer/radiant-rbac_base-extension}
63
+ s.rdoc_options = ["--charset=UTF-8"]
64
+ s.require_paths = ["lib"]
65
+ s.rubygems_version = %q{1.3.7}
66
+ s.summary = %q{RBAC Base Extension for Radiant CMS}
67
+ s.test_files = [
68
+ "spec/controllers/admin/roles_controller_spec.rb",
69
+ "spec/controllers/admin/roles_routing_spec.rb",
70
+ "spec/helpers/admin/roles_helper_spec.rb",
71
+ "spec/models/role_spec.rb",
72
+ "spec/models/user_spec.rb",
73
+ "spec/spec_helper.rb",
74
+ "spec/views/admin/roles/index_spec.rb",
75
+ "spec/views/admin/roles/show_spec.rb"
76
+ ]
77
+
78
+ if s.respond_to? :specification_version then
79
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
80
+ s.specification_version = 3
81
+
82
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
83
+ s.add_runtime_dependency(%q<radiant>, [">= 0.9"])
84
+ else
85
+ s.add_dependency(%q<radiant>, [">= 0.9"])
86
+ end
87
+ else
88
+ s.add_dependency(%q<radiant>, [">= 0.9"])
89
+ end
90
+ end
91
+