radiant-page_group_permissions-extension 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.textile +63 -0
- data/Rakefile +113 -0
- data/VERSION +1 -0
- data/app/controllers/admin/groups_controller.rb +65 -0
- data/app/helpers/groups_helper.rb +2 -0
- data/app/models/group.rb +16 -0
- data/app/views/admin/groups/_form.html.haml +25 -0
- data/app/views/admin/groups/edit.html.haml +3 -0
- data/app/views/admin/groups/index.html.haml +73 -0
- data/app/views/admin/groups/new.html.haml +3 -0
- data/app/views/admin/groups/remove.html.haml +23 -0
- data/app/views/admin/groups/remove_member.html.haml +14 -0
- data/app/views/admin/pages/_page_group_form_part.html.haml +5 -0
- data/app/views/admin/pages/_page_group_td.html.haml +5 -0
- data/app/views/admin/pages/_page_group_th.html.haml +1 -0
- data/config/routes.rb +12 -0
- data/db/migrate/001_create_groups.rb +38 -0
- data/db/migrate/002_alter_user_columns.rb +8 -0
- data/lib/controller_extensions.rb +27 -0
- data/lib/model_extensions.rb +18 -0
- data/lib/tasks/page_group_permissions_extension_tasks.rake +28 -0
- data/page_group_permissions_extension.rb +37 -0
- data/public/images/page_group_permissions/add-member.png +0 -0
- data/public/images/page_group_permissions/new-group.png +0 -0
- data/public/images/page_group_permissions/remove-member.png +0 -0
- data/spec/controllers/groups_controller_spec.rb +21 -0
- data/spec/helpers/groups_helper_spec.rb +5 -0
- data/spec/models/group_spec.rb +11 -0
- data/spec/spec.opts +6 -0
- data/spec/spec_helper.rb +37 -0
- metadata +118 -0
data/README.textile
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
h1. Page Group Permissions
|
2
|
+
|
3
|
+
Created by Matt Freels
|
4
|
+
|
5
|
+
This extension allows you to organize your users into groups and divide up site-editing privileges accordingly. It requires Radiant 0.8+ and the Shards extension found in the official Radiant repository.
|
6
|
+
|
7
|
+
h2. Installation
|
8
|
+
|
9
|
+
h3. From the Radiant Extension Registry
|
10
|
+
|
11
|
+
# From your RAILS_ROOT run:
|
12
|
+
<pre>script/extension install page_group_permissions</pre>
|
13
|
+
# Restart your app
|
14
|
+
NOTE: In some earlier versions of Radiant, the migrations may not run, and the assets may not be copied and you may therefore need to run:
|
15
|
+
<pre>rake radiant:extensions:page_group_permissions:migrate
|
16
|
+
rake radiant:extensions:page_group_permissions:update</pre>
|
17
|
+
|
18
|
+
h3. From Github
|
19
|
+
|
20
|
+
# From your RAILS_ROOT run:
|
21
|
+
<pre>cd vendor/extensions
|
22
|
+
git clone git://github.com/avonderluft/radiant-page_group_permissions-extension.git ./page_group_permissions
|
23
|
+
cd ../../
|
24
|
+
rake radiant:extensions:page_group_permissions:migrate
|
25
|
+
rake radiant:extensions:page_group_permissions:update
|
26
|
+
</pre>
|
27
|
+
# Restart your app
|
28
|
+
|
29
|
+
h3. Using the gem
|
30
|
+
|
31
|
+
# Install the gem
|
32
|
+
<pre>gem install radiant-page_group_permissions-extension</pre>
|
33
|
+
# Update your Radiant config: add to environment.rb with other gem.configs
|
34
|
+
<pre>config.gem 'radiant-page_group_permissions-extension', :lib => false</pre>
|
35
|
+
# Run database migrations
|
36
|
+
<pre>rake db:migrate:extensions</pre>
|
37
|
+
# Copy assets
|
38
|
+
<pre>rake radiant:extensions:update_all</pre>
|
39
|
+
# Restart your app
|
40
|
+
|
41
|
+
h2. Usage
|
42
|
+
|
43
|
+
Create and edit groups and add/remove members from the new groups tag.
|
44
|
+
Add page to a group by editing the page.
|
45
|
+
A member of a group has permission to edit any page owned by the group or children of said pages.
|
46
|
+
|
47
|
+
h2. Revision History
|
48
|
+
|
49
|
+
* 5/12/2011 - Compatible with >= 0.9 [Andrew vonderLuft, Jim Gay]
|
50
|
+
* 7/7/2009 - Updated to work with Radiant 0.8+ [Matthew Bass]
|
51
|
+
|
52
|
+
h2. To do
|
53
|
+
|
54
|
+
* Update Group index view to conform to Blade UI
|
55
|
+
* Create Help file for Help extension
|
56
|
+
|
57
|
+
h2. Contributors
|
58
|
+
|
59
|
+
* Matt Freels
|
60
|
+
* Nikos Dimitrakopoulos
|
61
|
+
* Jim Gay
|
62
|
+
* Matthew Bass
|
63
|
+
* Andrew vonderLuft
|
data/Rakefile
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
begin
|
2
|
+
require 'jeweler'
|
3
|
+
Jeweler::Tasks.new do |gem|
|
4
|
+
gem.name = "radiant-page_group_permissions-extension"
|
5
|
+
gem.summary = %Q{Page Group Permissions Extension for Radiant CMS}
|
6
|
+
gem.description = %Q{Enables you to organize users into groups and apply group-based edit permissions to the page hierarchy.}
|
7
|
+
gem.email = "avonderluft@avlux.net"
|
8
|
+
gem.homepage = "https://github.com/avonderluft/radiant-page_group_permissions-extension"
|
9
|
+
gem.authors = ['Matt Freels','Nikos Dimitrakopoulos','Jim Gay','Matthew Bass','Andrew vonderLuft']
|
10
|
+
gem.add_dependency 'radiant', ">=0.9.1"
|
11
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
12
|
+
end
|
13
|
+
rescue LoadError
|
14
|
+
puts "Jeweler (or a dependency) not available. This is only required if you plan to package page_group_permissions as a gem."
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
# I think this is the one that should be moved to the extension Rakefile template
|
20
|
+
|
21
|
+
# In rails 1.2, plugins aren't available in the path until they're loaded.
|
22
|
+
# Check to see if the rspec plugin is installed first and require
|
23
|
+
# it if it is. If not, use the gem version.
|
24
|
+
require File.join(File.dirname(__FILE__), '..', '..', '..', 'config', 'boot')
|
25
|
+
require 'rake'
|
26
|
+
require 'rake/rdoctask'
|
27
|
+
|
28
|
+
rspec_base = File.expand_path(File.dirname(__FILE__) + '/../../radiant/vendor/plugins/rspec/lib')
|
29
|
+
$LOAD_PATH.unshift(rspec_base) if File.exist?(rspec_base)
|
30
|
+
require 'spec/rake/spectask'
|
31
|
+
# require 'spec/translator'
|
32
|
+
|
33
|
+
extension_root = File.expand_path(File.dirname(__FILE__))
|
34
|
+
|
35
|
+
task :default => :spec
|
36
|
+
task :stats => "spec:statsetup"
|
37
|
+
|
38
|
+
desc "Run all specs in spec directory"
|
39
|
+
Spec::Rake::SpecTask.new(:spec) do |t|
|
40
|
+
t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
|
41
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
42
|
+
end
|
43
|
+
|
44
|
+
namespace :spec do
|
45
|
+
desc "Run all specs in spec directory with RCov"
|
46
|
+
Spec::Rake::SpecTask.new(:rcov) do |t|
|
47
|
+
t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
|
48
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
49
|
+
t.rcov = true
|
50
|
+
t.rcov_opts = ['--exclude', 'spec', '--rails']
|
51
|
+
end
|
52
|
+
|
53
|
+
desc "Print Specdoc for all specs"
|
54
|
+
Spec::Rake::SpecTask.new(:doc) do |t|
|
55
|
+
t.spec_opts = ["--format", "specdoc", "--dry-run"]
|
56
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
57
|
+
end
|
58
|
+
|
59
|
+
[:models, :controllers, :views, :helpers].each do |sub|
|
60
|
+
desc "Run the specs under spec/#{sub}"
|
61
|
+
Spec::Rake::SpecTask.new(sub) do |t|
|
62
|
+
t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
|
63
|
+
t.spec_files = FileList["spec/#{sub}/**/*_spec.rb"]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Hopefully no one has written their extensions in pre-0.9 style
|
68
|
+
# desc "Translate specs from pre-0.9 to 0.9 style"
|
69
|
+
# task :translate do
|
70
|
+
# translator = ::Spec::Translator.new
|
71
|
+
# dir = RAILS_ROOT + '/spec'
|
72
|
+
# translator.translate(dir, dir)
|
73
|
+
# end
|
74
|
+
|
75
|
+
# Setup specs for stats
|
76
|
+
task :statsetup do
|
77
|
+
require 'code_statistics'
|
78
|
+
::STATS_DIRECTORIES << %w(Model\ specs spec/models)
|
79
|
+
::STATS_DIRECTORIES << %w(View\ specs spec/views)
|
80
|
+
::STATS_DIRECTORIES << %w(Controller\ specs spec/controllers)
|
81
|
+
::STATS_DIRECTORIES << %w(Helper\ specs spec/views)
|
82
|
+
::CodeStatistics::TEST_TYPES << "Model specs"
|
83
|
+
::CodeStatistics::TEST_TYPES << "View specs"
|
84
|
+
::CodeStatistics::TEST_TYPES << "Controller specs"
|
85
|
+
::CodeStatistics::TEST_TYPES << "Helper specs"
|
86
|
+
::STATS_DIRECTORIES.delete_if {|a| a[0] =~ /test/}
|
87
|
+
end
|
88
|
+
|
89
|
+
namespace :db do
|
90
|
+
namespace :fixtures do
|
91
|
+
desc "Load fixtures (from spec/fixtures) into the current environment's database. Load specific fixtures using FIXTURES=x,y"
|
92
|
+
task :load => :environment do
|
93
|
+
require 'active_record/fixtures'
|
94
|
+
ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym)
|
95
|
+
(ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir.glob(File.join(RAILS_ROOT, 'spec', 'fixtures', '*.{yml,csv}'))).each do |fixture_file|
|
96
|
+
Fixtures.create_fixtures('spec/fixtures', File.basename(fixture_file, '.*'))
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
desc 'Generate documentation for the page_group_permissions extension.'
|
104
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
105
|
+
rdoc.rdoc_dir = 'rdoc'
|
106
|
+
rdoc.title = 'PageGroupPermissionsExtension'
|
107
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
108
|
+
rdoc.rdoc_files.include('README')
|
109
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
110
|
+
end
|
111
|
+
|
112
|
+
# Load any custom rakefiles for extension
|
113
|
+
Dir[File.dirname(__FILE__) + '/tasks/*.rake'].sort.each { |f| require f }
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.0.0
|
@@ -0,0 +1,65 @@
|
|
1
|
+
class Admin::GroupsController < Admin::ResourceController
|
2
|
+
model_class Group
|
3
|
+
|
4
|
+
only_allow_access_to :add_page, :add_member, :remove_member, :new, :create, :update, :edit, :remove, :index,
|
5
|
+
:when => [:admin],
|
6
|
+
:denied_url => { :controller => 'page', :action => 'index' },
|
7
|
+
:denied_message => 'You must have administrator privileges to perform this action.'
|
8
|
+
|
9
|
+
def add_page
|
10
|
+
page = Page.find params[:page_id]
|
11
|
+
|
12
|
+
begin
|
13
|
+
group = Group.find params[:group_id]
|
14
|
+
page.group = group
|
15
|
+
page.save
|
16
|
+
flash[:notice] = "Group for \"#{page.title}\" set to #{group.name}."
|
17
|
+
|
18
|
+
rescue ::ActiveRecord::RecordNotFound
|
19
|
+
page.group = nil
|
20
|
+
page.save
|
21
|
+
flash[:notice] = "Group removed from \"#{page.title}\"."
|
22
|
+
|
23
|
+
ensure
|
24
|
+
redirect_to :controller => 'admin/page', :action => 'index'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def add_member
|
29
|
+
if request.post?
|
30
|
+
@group = Group.find params[:id]
|
31
|
+
@user = User.find params[:user_id]
|
32
|
+
|
33
|
+
@group.users << @user
|
34
|
+
@group.save
|
35
|
+
flash[:notice] = "#{@user.name} added to #{@group.name}."
|
36
|
+
end
|
37
|
+
rescue ::ActiveRecord::RecordNotFound
|
38
|
+
if @group.nil?
|
39
|
+
flash[:error] = "Group not found for that id."
|
40
|
+
elsif @user.nil?
|
41
|
+
flash[:error] = "Please select a user to add to #{@group.name}."
|
42
|
+
end
|
43
|
+
ensure
|
44
|
+
redirect_to admin_groups_url
|
45
|
+
end
|
46
|
+
|
47
|
+
def remove_member
|
48
|
+
@group = Group.find params[:group_id]
|
49
|
+
@user = User.find params[:id]
|
50
|
+
|
51
|
+
if request.delete?
|
52
|
+
@group.users.delete @user
|
53
|
+
@group.save
|
54
|
+
flash[:notice] = "#{@user.name} removed from #{@group.name}."
|
55
|
+
redirect_to admin_groups_url
|
56
|
+
end
|
57
|
+
rescue
|
58
|
+
if @group.nil?
|
59
|
+
flash[:error] = "Group not found for that group id."
|
60
|
+
elsif @user.nil?
|
61
|
+
flash[:error] = "User not found for that user id."
|
62
|
+
end
|
63
|
+
redirect_to admin_groups_url
|
64
|
+
end
|
65
|
+
end
|
data/app/models/group.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
class Group < ActiveRecord::Base
|
2
|
+
unless self.respond_to?(:order_by)
|
3
|
+
default_scope :order => "name ASC"
|
4
|
+
else
|
5
|
+
order_by :name
|
6
|
+
end
|
7
|
+
|
8
|
+
belongs_to :created_by, :class_name => 'User', :foreign_key => 'created_by'
|
9
|
+
belongs_to :updated_by, :class_name => 'User', :foreign_key => 'updated_by'
|
10
|
+
|
11
|
+
has_and_belongs_to_many :users
|
12
|
+
has_many :pages
|
13
|
+
|
14
|
+
validates_presence_of :name, :message => 'required'
|
15
|
+
validates_length_of :name, :maximum => 100, :message => "%d-character limit"
|
16
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
.form-area
|
2
|
+
%p#group_title
|
3
|
+
%label{:for=>"group_name"} Name (Required)
|
4
|
+
%p.title= f.text_field "name", :class=>"textbox", :maxlength=>100
|
5
|
+
%br
|
6
|
+
%p.label
|
7
|
+
%label.optional{:for=>"group_notes"} Notes (Optional)
|
8
|
+
%p= f.text_area "notes", :class=>"group_textarea"
|
9
|
+
|
10
|
+
= updated_stamp @group
|
11
|
+
|
12
|
+
%p.buttons
|
13
|
+
= save_model_button(@group)
|
14
|
+
= save_model_and_continue_editing_button(@group)
|
15
|
+
or
|
16
|
+
= link_to "Cancel", admin_groups_url
|
17
|
+
|
18
|
+
= focus 'group_name'
|
19
|
+
|
20
|
+
- content_for :page_css do
|
21
|
+
:sass
|
22
|
+
.group_textarea
|
23
|
+
width: 99.5%
|
24
|
+
height: 100px
|
25
|
+
font-size: 120%
|
@@ -0,0 +1,73 @@
|
|
1
|
+
- if Radiant::Version.to_s < '0.9'
|
2
|
+
%h1 Groups
|
3
|
+
|
4
|
+
.outset
|
5
|
+
%table#groups.index{:border => "0", :cellpadding => "0", :cellspacing => "0"}
|
6
|
+
%thead
|
7
|
+
%tr
|
8
|
+
%th Name
|
9
|
+
%th{:colspan => "2"} Modify
|
10
|
+
%tbody
|
11
|
+
- models.each do |group|
|
12
|
+
%tr.node
|
13
|
+
%td.group
|
14
|
+
= link_to group.name, :action => 'edit', :id => group.id
|
15
|
+
%small.note= h group.notes
|
16
|
+
%td.add-child
|
17
|
+
- form_tag add_member_admin_group_path(group) do
|
18
|
+
=select_tag :user_id, options_for_select(User.find(:all, :order => 'name ASC').map{|u| [u.name, u.id]}.unshift(['—', '']))
|
19
|
+
= image_submit_tag('page_group_permissions/add-member.png', :alt => 'Add Group Member')
|
20
|
+
%td
|
21
|
+
= link_to image('remove', :alt => 'Remove Group'), remove_admin_group_path(group), :class => "action"
|
22
|
+
- group.users.each do |user|
|
23
|
+
%tr.user
|
24
|
+
%td.name{:colspan => "2"}
|
25
|
+
= link_to user.name, edit_admin_user_path(user)
|
26
|
+
%td
|
27
|
+
= link_to image_tag('page_group_permissions/remove-member.png', :alt => 'Remove Group Member'), remove_member_admin_group_path(group, user), :class => "action"
|
28
|
+
- if group.users.empty?
|
29
|
+
%tr.user
|
30
|
+
%td.none{:colspan => "3"} no members
|
31
|
+
%tbody
|
32
|
+
%p.notes= link_to image_tag('page_group_permissions/new-group.png', :alt => 'New Group'), :action => 'new'
|
33
|
+
|
34
|
+
%p.notes Use groups to organize your normal users into publishing teams, with rights to modify certain sections of your site. A user can belong to any number of groups. When a page is owned by a group, its members may edit the page or any underneath it in the site hierarchy. Administrators and Developers can be added to groups, but they already have editing rights to all pages.
|
35
|
+
|
36
|
+
- content_for :page_css do
|
37
|
+
:sass
|
38
|
+
#content table.index
|
39
|
+
.node .group
|
40
|
+
font-size: 115%
|
41
|
+
font-weight: bold
|
42
|
+
.user .name
|
43
|
+
font-size: 107%
|
44
|
+
a
|
45
|
+
color: #444
|
46
|
+
text-decoration: none
|
47
|
+
.node .group a
|
48
|
+
color: black
|
49
|
+
margin-left: 5px
|
50
|
+
text-decoration: none
|
51
|
+
&:hover
|
52
|
+
color: blue
|
53
|
+
text-decoration: underline
|
54
|
+
.user
|
55
|
+
.name
|
56
|
+
a:hover
|
57
|
+
color: blue
|
58
|
+
text-decoration: underline
|
59
|
+
padding-left: 26px
|
60
|
+
.none
|
61
|
+
padding-left: 26px
|
62
|
+
.node .note, .user .none
|
63
|
+
color: #666
|
64
|
+
font-size: 90%
|
65
|
+
font-style: italic
|
66
|
+
font-weight: normal
|
67
|
+
margin-left: .5em
|
68
|
+
.node .add-child
|
69
|
+
width: 200px
|
70
|
+
form
|
71
|
+
margin: 0
|
72
|
+
.notes
|
73
|
+
margin: 24px
|
@@ -0,0 +1,23 @@
|
|
1
|
+
%h1 Remove Group
|
2
|
+
.inset
|
3
|
+
%p
|
4
|
+
Are you sure you want to
|
5
|
+
%strong.warning permanently remove
|
6
|
+
the following group?
|
7
|
+
%table#site-map.index{:border => "0", :cellpadding => "0", :cellspacing => "0"}
|
8
|
+
%tbody
|
9
|
+
%tr.node{:onmouseout => "Element.removeClassName(this, 'highlight');", :onmouseover => "Element.addClassName(this, 'highlight');"}
|
10
|
+
%td.group
|
11
|
+
= @group.name
|
12
|
+
|
13
|
+
- form_for :group, :url => admin_group_path(@group), :html => {:method => :delete} do
|
14
|
+
%p.buttons
|
15
|
+
= submit_tag "Delete Group", :class => 'button'
|
16
|
+
or
|
17
|
+
=link_to 'Cancel', admin_groups_path
|
18
|
+
|
19
|
+
- content_for :page_css do
|
20
|
+
:sass
|
21
|
+
#content table.index .node .group
|
22
|
+
font-size: 115%
|
23
|
+
font-weight: bold
|
@@ -0,0 +1,14 @@
|
|
1
|
+
%h1 Remove Member
|
2
|
+
.inset
|
3
|
+
%p
|
4
|
+
Are you sure you want to remove
|
5
|
+
%strong= h @user.name
|
6
|
+
from the group
|
7
|
+
= succeed "?" do
|
8
|
+
%strong= @group.name
|
9
|
+
|
10
|
+
- form_tag '', :method => :delete do
|
11
|
+
%p.buttons
|
12
|
+
= submit_tag "Remove Member", :class => 'button'
|
13
|
+
or
|
14
|
+
= link_to "Cancel", admin_groups_url
|
@@ -0,0 +1,5 @@
|
|
1
|
+
- if current_user.admin?
|
2
|
+
%p#group-id
|
3
|
+
%label{:for => "page_group_id"} Owning Group:
|
4
|
+
%select#page_group_id{:name => "page[group_id]"}
|
5
|
+
= options_for_select(Group.find(:all, :order => 'name ASC').map{|g| [g.name, g.id]}.unshift(['—', '']), (@page.group.nil? ? '' : @page.group.id))
|
@@ -0,0 +1 @@
|
|
1
|
+
%th.group Group
|
data/config/routes.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
ActionController::Routing::Routes.draw do |map|
|
2
|
+
if Group.table_exists?
|
3
|
+
map.namespace :admin do |admin|
|
4
|
+
admin.resources :groups
|
5
|
+
end
|
6
|
+
map.with_options(:controller => 'admin/groups') do |group|
|
7
|
+
group.remove_admin_group 'admin/groups/:id/remove', :action => 'remove', :conditions => {:method => :get}
|
8
|
+
group.add_member_admin_group 'admin/groups/:id/add_member', :action => 'add_member', :conditions => {:method => :post}
|
9
|
+
group.remove_member_admin_group 'admin/groups/:group_id/remove_member/:id', :action => 'remove_member'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class CreateGroups < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
User.send :has_and_belongs_to_many, :groups
|
4
|
+
Page.send :belongs_to, :group
|
5
|
+
create_table :groups do |t|
|
6
|
+
t.string :name
|
7
|
+
t.text :notes
|
8
|
+
t.integer :created_by, :updated_by
|
9
|
+
|
10
|
+
t.timestamps
|
11
|
+
end
|
12
|
+
|
13
|
+
create_table(:groups_users, :id => false) do |t|
|
14
|
+
t.integer :group_id, :user_id
|
15
|
+
end
|
16
|
+
add_index :groups_users, :group_id
|
17
|
+
add_index :groups_users, :user_id
|
18
|
+
|
19
|
+
add_column :pages, :group_id, :integer
|
20
|
+
|
21
|
+
#Add a default group to own the home page
|
22
|
+
Group.reset_column_information
|
23
|
+
Page.reset_column_information
|
24
|
+
|
25
|
+
g = Group.create(:name => 'Site Editors')
|
26
|
+
p = Page.find_by_parent_id(nil)
|
27
|
+
if p
|
28
|
+
p.group = g
|
29
|
+
p.save
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.down
|
34
|
+
remove_column :pages, :group_id
|
35
|
+
drop_table :groups
|
36
|
+
drop_table :groups_users
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
PageControllerExtensions = Proc.new do
|
2
|
+
|
3
|
+
only_allow_access_to :new, :edit, :create, :update, :remove, :destroy,
|
4
|
+
:if => :user_is_in_page_group,
|
5
|
+
:denied_url => :back,
|
6
|
+
:denied_message => "You must have group privileges to perform this action."
|
7
|
+
|
8
|
+
def user_is_in_page_group
|
9
|
+
return true if current_user.admin? || current_user.designer_or_developer?
|
10
|
+
|
11
|
+
page = Page.find(params[:id] || params[:page_id] || params[:parent_id] || params[:page][:parent_id])
|
12
|
+
|
13
|
+
until page.nil? do
|
14
|
+
return true if page.group_owners.include? current_user
|
15
|
+
page = page.parent
|
16
|
+
end
|
17
|
+
|
18
|
+
return false
|
19
|
+
end
|
20
|
+
|
21
|
+
before_filter :disallow_group_edits
|
22
|
+
def disallow_group_edits
|
23
|
+
if params[:page] && !current_user.admin?
|
24
|
+
params[:page].delete(:group_id.to_s)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
PageModelExtensions = Proc.new do
|
2
|
+
belongs_to :group
|
3
|
+
|
4
|
+
def group_owners
|
5
|
+
self.group.nil? ? [] : self.group.users
|
6
|
+
end
|
7
|
+
|
8
|
+
def group_name
|
9
|
+
self.group.nil? ? '' : self.group.name
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
UserModelExtensions = Proc.new do
|
14
|
+
has_and_belongs_to_many :groups
|
15
|
+
def designer_or_developer?
|
16
|
+
respond_to?(:designer?) ? designer? : developer?
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
namespace :radiant do
|
2
|
+
namespace :extensions do
|
3
|
+
namespace :page_group_permissions do
|
4
|
+
|
5
|
+
desc "Runs the migration of the Page Group Permissions extension"
|
6
|
+
task :migrate => :environment do
|
7
|
+
require 'radiant/extension_migrator'
|
8
|
+
if ENV["VERSION"]
|
9
|
+
PageGroupPermissionsExtension.migrator.migrate(ENV["VERSION"].to_i)
|
10
|
+
else
|
11
|
+
PageGroupPermissionsExtension.migrator.migrate
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
desc "Copies public assets of the Page Group Permissions to the instance public/ directory."
|
16
|
+
task :update => :environment do
|
17
|
+
is_svn_or_dir = proc {|path| path =~ /\.svn/ || File.directory?(path) }
|
18
|
+
Dir[PageGroupPermissionsExtension.root + "/public/**/*"].reject(&is_svn_or_dir).each do |file|
|
19
|
+
path = file.sub(PageGroupPermissionsExtension.root, '')
|
20
|
+
directory = File.dirname(path)
|
21
|
+
puts "Copying #{path}..."
|
22
|
+
mkdir_p RAILS_ROOT + directory
|
23
|
+
cp file, RAILS_ROOT + path
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require_dependency 'model_extensions'
|
2
|
+
require_dependency 'controller_extensions'
|
3
|
+
|
4
|
+
# Uncomment this if you reference any of your controllers in activate
|
5
|
+
begin
|
6
|
+
require_dependency 'application_controller'
|
7
|
+
rescue MissingSourceFile
|
8
|
+
require_dependency 'application'
|
9
|
+
end
|
10
|
+
|
11
|
+
class PageGroupPermissionsExtension < Radiant::Extension
|
12
|
+
|
13
|
+
version "#{File.read(File.expand_path(File.dirname(__FILE__)) + '/VERSION')}"
|
14
|
+
description "Enables you to organize users into groups and apply group-based edit permissions to the page hierarchy."
|
15
|
+
url "https://github.com/avonderluft/radiant-page_group_permissions-extension"
|
16
|
+
|
17
|
+
def activate
|
18
|
+
if Group.table_exists?
|
19
|
+
User.module_eval &UserModelExtensions
|
20
|
+
Page.module_eval &PageModelExtensions
|
21
|
+
Admin::PagesController.module_eval &PageControllerExtensions
|
22
|
+
UserActionObserver.instance.send :add_observer!, Group
|
23
|
+
|
24
|
+
if self.respond_to?(:tab)
|
25
|
+
add_tab "Settings" do
|
26
|
+
add_item "Groups", "/admin/groups", :after => "Users", :visibility => [:admin]
|
27
|
+
end
|
28
|
+
else
|
29
|
+
admin.tabs.add "Groups", "/admin/groups", :after => "Layouts", :visibility => [:admin]
|
30
|
+
end
|
31
|
+
admin.pages.index.add :node, "page_group_td", :before => "status_column"
|
32
|
+
admin.pages.index.add :sitemap_head, "page_group_th", :before => "status_column_header"
|
33
|
+
admin.pages.edit.add :parts_bottom, "page_group_form_part", :after => "edit_timestamp"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Admin::GroupsController do
|
4
|
+
dataset :users
|
5
|
+
|
6
|
+
before do
|
7
|
+
@group_1 = Group.create!(:name => 'Z Group 1')
|
8
|
+
@group_2 = Group.create!(:name => 'Group 1')
|
9
|
+
@group_3 = Group.create!(:name => 'Group 2')
|
10
|
+
@groups = [@group_2, @group_3, @group_1]
|
11
|
+
login_as :admin
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "index with GET request" do
|
15
|
+
it "should order Groups by name" do
|
16
|
+
get :index
|
17
|
+
assigns(:groups).should == @groups
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
unless defined? RADIANT_ROOT
|
2
|
+
ENV["RAILS_ENV"] = "test"
|
3
|
+
case
|
4
|
+
when ENV["RADIANT_ENV_FILE"]
|
5
|
+
require ENV["RADIANT_ENV_FILE"]
|
6
|
+
when File.dirname(__FILE__) =~ %r{vendor/radiant/vendor/extensions}
|
7
|
+
require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../../../")}/config/environment"
|
8
|
+
else
|
9
|
+
require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../")}/config/environment"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
require "#{RADIANT_ROOT}/spec/spec_helper"
|
13
|
+
|
14
|
+
if File.directory?(File.dirname(__FILE__) + "/scenarios")
|
15
|
+
Scenario.load_paths.unshift File.dirname(__FILE__) + "/scenarios"
|
16
|
+
end
|
17
|
+
if File.directory?(File.dirname(__FILE__) + "/matchers")
|
18
|
+
Dir[File.dirname(__FILE__) + "/matchers/*.rb"].each {|file| require file }
|
19
|
+
end
|
20
|
+
|
21
|
+
Spec::Runner.configure do |config|
|
22
|
+
# config.use_transactional_fixtures = true
|
23
|
+
# config.use_instantiated_fixtures = false
|
24
|
+
# config.fixture_path = RAILS_ROOT + '/spec/fixtures'
|
25
|
+
|
26
|
+
# You can declare fixtures for each behaviour like this:
|
27
|
+
# describe "...." do
|
28
|
+
# fixtures :table_a, :table_b
|
29
|
+
#
|
30
|
+
# Alternatively, if you prefer to declare them only once, you can
|
31
|
+
# do so here, like so ...
|
32
|
+
#
|
33
|
+
# config.global_fixtures = :table_a, :table_b
|
34
|
+
#
|
35
|
+
# If you declare global fixtures, be aware that they will be declared
|
36
|
+
# for all of your examples, even those that don't use them.
|
37
|
+
end
|
metadata
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: radiant-page_group_permissions-extension
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 23
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
- 0
|
10
|
+
version: 1.0.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Matt Freels
|
14
|
+
- Nikos Dimitrakopoulos
|
15
|
+
- Jim Gay
|
16
|
+
- Matthew Bass
|
17
|
+
- Andrew vonderLuft
|
18
|
+
autorequire:
|
19
|
+
bindir: bin
|
20
|
+
cert_chain: []
|
21
|
+
|
22
|
+
date: 2011-05-12 00:00:00 -07:00
|
23
|
+
default_executable:
|
24
|
+
dependencies:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: radiant
|
27
|
+
prerelease: false
|
28
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
hash: 57
|
34
|
+
segments:
|
35
|
+
- 0
|
36
|
+
- 9
|
37
|
+
- 1
|
38
|
+
version: 0.9.1
|
39
|
+
type: :runtime
|
40
|
+
version_requirements: *id001
|
41
|
+
description: Enables you to organize users into groups and apply group-based edit permissions to the page hierarchy.
|
42
|
+
email: avonderluft@avlux.net
|
43
|
+
executables: []
|
44
|
+
|
45
|
+
extensions: []
|
46
|
+
|
47
|
+
extra_rdoc_files:
|
48
|
+
- README.textile
|
49
|
+
files:
|
50
|
+
- README.textile
|
51
|
+
- Rakefile
|
52
|
+
- VERSION
|
53
|
+
- app/controllers/admin/groups_controller.rb
|
54
|
+
- app/helpers/groups_helper.rb
|
55
|
+
- app/models/group.rb
|
56
|
+
- app/views/admin/groups/_form.html.haml
|
57
|
+
- app/views/admin/groups/edit.html.haml
|
58
|
+
- app/views/admin/groups/index.html.haml
|
59
|
+
- app/views/admin/groups/new.html.haml
|
60
|
+
- app/views/admin/groups/remove.html.haml
|
61
|
+
- app/views/admin/groups/remove_member.html.haml
|
62
|
+
- app/views/admin/pages/_page_group_form_part.html.haml
|
63
|
+
- app/views/admin/pages/_page_group_td.html.haml
|
64
|
+
- app/views/admin/pages/_page_group_th.html.haml
|
65
|
+
- config/routes.rb
|
66
|
+
- db/migrate/001_create_groups.rb
|
67
|
+
- db/migrate/002_alter_user_columns.rb
|
68
|
+
- lib/controller_extensions.rb
|
69
|
+
- lib/model_extensions.rb
|
70
|
+
- lib/tasks/page_group_permissions_extension_tasks.rake
|
71
|
+
- page_group_permissions_extension.rb
|
72
|
+
- public/images/page_group_permissions/add-member.png
|
73
|
+
- public/images/page_group_permissions/new-group.png
|
74
|
+
- public/images/page_group_permissions/remove-member.png
|
75
|
+
- spec/controllers/groups_controller_spec.rb
|
76
|
+
- spec/helpers/groups_helper_spec.rb
|
77
|
+
- spec/models/group_spec.rb
|
78
|
+
- spec/spec.opts
|
79
|
+
- spec/spec_helper.rb
|
80
|
+
has_rdoc: true
|
81
|
+
homepage: https://github.com/avonderluft/radiant-page_group_permissions-extension
|
82
|
+
licenses: []
|
83
|
+
|
84
|
+
post_install_message:
|
85
|
+
rdoc_options: []
|
86
|
+
|
87
|
+
require_paths:
|
88
|
+
- lib
|
89
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
hash: 3
|
95
|
+
segments:
|
96
|
+
- 0
|
97
|
+
version: "0"
|
98
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
|
+
none: false
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
hash: 3
|
104
|
+
segments:
|
105
|
+
- 0
|
106
|
+
version: "0"
|
107
|
+
requirements: []
|
108
|
+
|
109
|
+
rubyforge_project:
|
110
|
+
rubygems_version: 1.5.2
|
111
|
+
signing_key:
|
112
|
+
specification_version: 3
|
113
|
+
summary: Page Group Permissions Extension for Radiant CMS
|
114
|
+
test_files:
|
115
|
+
- spec/controllers/groups_controller_spec.rb
|
116
|
+
- spec/helpers/groups_helper_spec.rb
|
117
|
+
- spec/models/group_spec.rb
|
118
|
+
- spec/spec_helper.rb
|