Skip to content

Commit

Permalink
merge
Browse files Browse the repository at this point in the history
  • Loading branch information
saturnflyer committed Jul 25, 2010
2 parents eb50cc2 + a9c264b commit 187475d
Show file tree
Hide file tree
Showing 26 changed files with 325 additions and 193 deletions.
9 changes: 6 additions & 3 deletions HELP_developer.md
Expand Up @@ -12,7 +12,10 @@ to return a boolean value based on the user being in that role.
By setting `allow_empty` to `false`, the role management interface will
not allow the last user to be removed from your role.

Once you have the role you need, you can even set the visibility of any
tabs that you create in your extension with your new role:
Once you have the role you need, you can set the visibility of any
controllers that you create in your extension with your new role:

admin.tabs.add "Finance", "/admin/finance", :after => "Pages", :visibility => [:finance]
only_allow_access_to :index, :show, :new, :create, :edit, :update, :remove, :destroy,
:when => [:designer, :admin],
:denied_url => { :controller => 'admin/pages', :action => 'index' },
:denied_message => 'You must have designer privileges to perform this action.'
30 changes: 28 additions & 2 deletions Rakefile
@@ -1,4 +1,18 @@
# I think this is the one that should be moved to the extension Rakefile template
begin
require 'jeweler'
Jeweler::Tasks.new do |gem|
gem.name = "radiant-rbac_base-extension"
gem.summary = %Q{RBAC Base Extension for Radiant CMS}
gem.description = %Q{Flexible user role management for Radiant.}
gem.email = "jim@saturnflyer.com"
gem.homepage = "http://github.com/saturnflyer/radiant-rbac_base-extension"
gem.authors = ["Jim Gay"]
gem.add_dependency 'radiant', '>= 0.9'
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
end
rescue LoadError
puts "Jeweler (or a dependency) not available. This is only required if you plan to package rbac_base as a gem."
end

# In rails 1.2, plugins aren't available in the path until they're loaded.
# Check to see if the rspec plugin is installed first and require
Expand All @@ -24,7 +38,8 @@ require 'rake/testtask'
rspec_base = File.expand_path(RADIANT_ROOT + '/vendor/plugins/rspec/lib')
$LOAD_PATH.unshift(rspec_base) if File.exist?(rspec_base)
require 'spec/rake/spectask'
# require 'spec/translator'
require 'cucumber'
require 'cucumber/rake/task'

# Cleanup the RADIANT_ROOT constant so specs will load the environment
Object.send(:remove_const, :RADIANT_ROOT)
Expand All @@ -40,6 +55,8 @@ Spec::Rake::SpecTask.new(:spec) do |t|
t.spec_files = FileList['spec/**/*_spec.rb']
end

task :features => 'spec:integration'

namespace :spec do
desc "Run all specs in spec directory with RCov"
Spec::Rake::SpecTask.new(:rcov) do |t|
Expand All @@ -62,6 +79,15 @@ namespace :spec do
t.spec_files = FileList["spec/#{sub}/**/*_spec.rb"]
end
end

desc "Run the Cucumber features"
Cucumber::Rake::Task.new(:integration) do |t|
t.fork = true
t.cucumber_opts = ['--format', (ENV['CUCUMBER_FORMAT'] || 'pretty')]
# t.feature_pattern = "#{extension_root}/features/**/*.feature"
t.profile = "default"
end

# Setup specs for stats
task :statsetup do
require 'code_statistics'
Expand Down
1 change: 1 addition & 0 deletions VERSION
@@ -0,0 +1 @@
1.3.1
2 changes: 1 addition & 1 deletion app/controllers/admin/roles_controller.rb
Expand Up @@ -39,7 +39,7 @@ def create

def destroy
@role = Role.find(params[:id])
@role.destroy unless Role::RADIANT_STANDARDS.include?(@role.role_name)
@role.destroy unless @role.standard?
redirect_to admin_roles_path()
rescue ActiveRecord::RecordNotFound
flash[:error] = 'The specified Role could not be found.'
Expand Down
5 changes: 1 addition & 4 deletions app/helpers/admin/roles_helper.rb
@@ -1,8 +1,5 @@
module Admin::RolesHelper
def role_spinner(which)
image('spinner.gif',
:class => 'busy', :id => "busy_#{which}",
:alt => "", :title => "",
:style => 'display: none;')
image('spinner.gif', :alt => "loading...")
end
end
4 changes: 2 additions & 2 deletions app/models/role.rb
Expand Up @@ -10,10 +10,10 @@ class ProtectedRoleError < StandardError; end

before_destroy :verify_non_standard

RADIANT_STANDARDS = ['admin', 'developer']
RADIANT_STANDARDS = ['admin', 'designer']

def verify_non_standard
if RADIANT_STANDARDS.include?(self[:role_name].to_s)
if standard?
raise Role::ProtectedRoleError, "`#{self[:role_name]}' is a protected role and may not be removed."
end
end
Expand Down
19 changes: 9 additions & 10 deletions app/views/admin/roles/edit.html.haml
@@ -1,19 +1,18 @@
- include_stylesheet 'rbac/rbac'
- include_javascript 'admin/dragdrop'
- include_javascript 'rbac/admin/role_details'
%h1= "Role: #{@role.role_name}"
- include_stylesheet 'rbac/rbac'
- @body_classes ||= [].tap{|a| a << 'reversed'}
%h1= @role.role_name
%script{:language => "javascript"}
= "var role_id = #{@role.id};"
%p Drag and drop users between the lists below to add or remove them from this role. The changes that you make will take effect immediately.
%h2
Active Users
= role_spinner 'taken'
%h2 Active Users
%ul#taken_users.UserList{:multiple => "multiple"}
%li#busy_taken.rbac_busy_marker= role_spinner 'taken'

%h2
Available Users
= role_spinner 'available'
%h2 Available Users
%ul#available_users.UserList{:multiple => "multiple"}
%li#busy_available.rbac_busy_marker= role_spinner 'available'

%h3 Edit Role Details
.form-area
Expand All @@ -22,8 +21,8 @@
= f.label :description
= f.text_field :description, :class => 'textbox'
%p
= f.check_box :allow_empty
= f.label :allow_empty, "Allow this role to have no users."
= f.check_box :allow_empty, :class => 'checkbox'
= f.label :allow_empty, "Allow this role to have no users.", :class => 'checkbox'
%p
= f.submit
or
Expand Down
33 changes: 20 additions & 13 deletions app/views/admin/roles/index.html.haml
Expand Up @@ -5,19 +5,26 @@
Roles are defined as a security mechanism for the extensions that are restricted by user role. User roles are normally added by these extensions at installation time. Removing roles may cause problems with the role based security.
%strong Only remove roles if you absolutely must.
%h2 Roles
%ul#role_list
- unless @roles.blank?
- @roles.each do |role|
%li
%span.role
= link_to role.role_name, admin_role_path(role)
= "(#{role.users.count})"
%span.description
%em= role.description
- unless role.standard?
%span.remover= link_to image('remove', :alt => 'remove role'), admin_role_path(role), :confirm => "Are you sure?", :method => :delete
- else
%li.none No Roles yet created.
%table.index
%thead
%tr
%th Role
%th # Users
%th Description
%th Modify
%tbody
- unless @roles.blank?
- @roles.each do |role|
%tr
%td= link_to role.role_name, admin_role_path(role)
%td= role.users.count
%td= role.description
%td.remove
- unless role.standard?
= link_to 'Remove', admin_role_path(role), :confirm => "Are you sure?", :method => :delete
- else
%tr
%td{ :colspan => 4} No Roles yet created.
#actions
= render :partial => 'add_role_form'
- include_stylesheet 'rbac/rbac'
3 changes: 3 additions & 0 deletions config/locales/en.yml
@@ -0,0 +1,3 @@
---
en:
rbac base: Rbac Base
1 change: 1 addition & 0 deletions cucumber.yml
@@ -0,0 +1 @@
default: --format progress features --tags ~@proposed,~@in_progress
8 changes: 4 additions & 4 deletions db/migrate/003_setup_standard_roles.rb
Expand Up @@ -2,11 +2,11 @@ class SetupStandardRoles < ActiveRecord::Migration
def self.up
User.send :has_and_belongs_to_many, :roles
self.setup_admins
self.setup_developers
self.setup_designers
end
def self.down
say("Removing all Roles.")
Role.find(:all, :conditions => ["role_name = 'Admin' OR role_name = 'Developer'"]).map(&:destroy)
Role.find(:all, :conditions => ["role_name = ? OR role_name = ?",'Admin','Designer']).map(&:destroy)
end

def self.setup_admins
Expand All @@ -17,8 +17,8 @@ def self.setup_admins
user.roles << admin_role
end
end

def self.setup_developers
def self.setup_designers
designer_users = User.find_all_by_designer(true)
designer_role = Role.create!(:role_name => 'Designer')
designer_users.each do |user|
Expand Down
4 changes: 2 additions & 2 deletions db/migrate/005_add_standard_role_details.rb
@@ -1,11 +1,11 @@
class AddStandardRoleDetails < ActiveRecord::Migration
def self.up
Role.find(:all).each do |role|
if role.name == 'Admin'
if role.role_name == 'Admin'
say("Adding Admin description.")
role.update_attributes({:allow_empty => false,
:description => %{Users in the Admin role, by default, have access to all features of the system.}})
elsif role.name == 'Designer'
elsif role.role_name == 'Designer'
say("Adding Designer description.")
role.update_attributes({:allow_empty => true,
:description => %{Users in the Designer role, by default, have access to all features of the system except user management.}})
Expand Down
13 changes: 13 additions & 0 deletions db/migrate/20100705182511_rename_role_developer_to_designer.rb
@@ -0,0 +1,13 @@
class RenameRoleDeveloperToDesigner < ActiveRecord::Migration
def self.up
if role = Role.find_by_role_name('Developer')
role.update_attribute(:role_name, 'Designer')
end
end

def self.down
if role = Role.find_by_role_name('Designer')
role.update_attribute(:role_name, 'Developer')
end
end
end
16 changes: 16 additions & 0 deletions features/support/env.rb
@@ -0,0 +1,16 @@
# Sets up the Rails environment for Cucumber
ENV["RAILS_ENV"] = "test"
# Extension root
extension_env = File.expand_path(File.dirname(__FILE__) + '/../../../../../config/environment')
require extension_env+'.rb'

Dir.glob(File.join(RADIANT_ROOT, "features", "**", "*.rb")).each {|step| require step}

Cucumber::Rails::World.class_eval do
include Dataset
datasets_directory "#{RADIANT_ROOT}/spec/datasets"
Dataset::Resolver.default = Dataset::DirectoryResolver.new("#{RADIANT_ROOT}/spec/datasets", File.dirname(__FILE__) + '/../../spec/datasets', File.dirname(__FILE__) + '/../datasets')
self.datasets_database_dump_path = "#{Rails.root}/tmp/dataset"

# dataset :rbac_base
end
14 changes: 14 additions & 0 deletions features/support/paths.rb
@@ -0,0 +1,14 @@
def path_to(page_name)
case page_name

when /the homepage/i
root_path

when /login/i
login_path
# Add more page name => path mappings here

else
raise "Can't find mapping from \"#{page_name}\" to a path."
end
end
37 changes: 32 additions & 5 deletions lib/tasks/rbac_base_extension_tasks.rake
Expand Up @@ -7,22 +7,49 @@ namespace :radiant do
require 'radiant/extension_migrator'
if ENV["VERSION"]
RbacBaseExtension.migrator.migrate(ENV["VERSION"].to_i)
Rake::Task['db:schema:dump'].invoke
else
RbacBaseExtension.migrator.migrate
Rake::Task['db:schema:dump'].invoke
end
end

desc "Copies the public assets of the Rbac_Base extension into the instance's public directory."
desc "Copies public assets of the Rbac Base to the instance public/ directory."
task :update => :environment do
is_svn_or_dir = proc {|path| path =~ /\.svn/ || File.directory?(path) }
puts "Copying assets from RbacBaseExtension"
Dir[RbacBaseExtension.root + "/public/**/*"].reject(&is_svn_or_dir).each do |file|
path = file.sub(RbacBaseExtension.root, '')
directory = File.dirname(path)
puts "Copying #{path}..."
mkdir_p RAILS_ROOT + directory
cp file, RAILS_ROOT + path
mkdir_p RAILS_ROOT + directory, :verbose => false
cp file, RAILS_ROOT + path, :verbose => false
end
unless RbacBaseExtension.root.starts_with? RAILS_ROOT # don't need to copy vendored tasks
puts "Copying rake tasks from RbacBaseExtension"
local_tasks_path = File.join(RAILS_ROOT, %w(lib tasks))
mkdir_p local_tasks_path, :verbose => false
Dir[File.join RbacBaseExtension.root, %w(lib tasks *.rake)].each do |file|
cp file, local_tasks_path, :verbose => false
end
end
end

desc "Syncs all available translations for this ext to the English ext master"
task :sync => :environment do
# The main translation root, basically where English is kept
language_root = RbacBaseExtension.root + "/config/locales"
words = TranslationSupport.get_translation_keys(language_root)

Dir["#{language_root}/*.yml"].each do |filename|
next if filename.match('_available_tags')
basename = File.basename(filename, '.yml')
puts "Syncing #{basename}"
(comments, other) = TranslationSupport.read_file(filename, basename)
words.each { |k,v| other[k] ||= words[k] } # Initializing hash variable as empty if it does not exist
other.delete_if { |k,v| !words[k] } # Remove if not defined in en.yml
TranslationSupport.write_file(filename, basename, comments, other)
end
end
end
end
end
end
46 changes: 8 additions & 38 deletions public/stylesheets/rbac/rbac.css
@@ -1,50 +1,20 @@
#role_list {
list-style: none;
margin: 0;
padding: 0;
}
#role_list li {
border-bottom: 1px solid #efefef;
margin: 0;
padding: 5px 5px 5px 25px;
position: relative;
line-height: 1.8;
}
#role_list li.none {
background: #eee;
color: #999;
}
#role_list li a {
border: 1px solid transparent;
padding: 3px;
text-decoration: none;
}
#role_list li a:hover {
border-color: black;
color: black;
}
#role_list li span.remover {
display: block;
position: absolute;
top: 5px;
right: 5px;
}
#role_list li span.remover a, #role_list li span.remover a:hover {
background: #fff;
}
ul.UserList {
background: #eee;
.UserList {
background: #fff;
color: #000;
list-style: none;
margin: 0 0 1em;
min-height: 1em;
padding: 10px 0;
}
ul.UserList.hover {
.UserList.hover {
background: #efe;
}
ul.UserList li {
.UserList li {
line-height: 1.2em;
list-style: none;
margin: 0;
padding: 2px 2px 2px 25px;
}
.rbac_busy_marker {
position: absolute;
}

0 comments on commit 187475d

Please sign in to comment.