radiant-rbac_base-extension 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
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
+