Designers cannot set others to admins, fixes #197
This commit is contained in:
parent
4c55401728
commit
03b6649742
@ -15,6 +15,8 @@ module Admin
|
|||||||
|
|
||||||
before_filter :set_locale
|
before_filter :set_locale
|
||||||
|
|
||||||
|
before_filter :set_current_thread_variables
|
||||||
|
|
||||||
helper_method :sections, :current_site_url, :site_url, :page_url, :current_ability
|
helper_method :sections, :current_site_url, :site_url, :page_url, :current_ability
|
||||||
|
|
||||||
# https://rails.lighthouseapp.com/projects/8994/tickets/1905-apphelpers-within-plugin-not-being-mixed-in
|
# https://rails.lighthouseapp.com/projects/8994/tickets/1905-apphelpers-within-plugin-not-being-mixed-in
|
||||||
@ -42,6 +44,11 @@ module Admin
|
|||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
|
def set_current_thread_variables
|
||||||
|
Thread.current[:admin] = current_admin
|
||||||
|
Thread.current[:site] = current_site
|
||||||
|
end
|
||||||
|
|
||||||
def current_ability
|
def current_ability
|
||||||
@current_ability ||= Ability.new(current_admin, current_site)
|
@current_ability ||= Ability.new(current_admin, current_site)
|
||||||
end
|
end
|
||||||
|
@ -65,7 +65,9 @@ class Ability
|
|||||||
|
|
||||||
can :manage, Membership
|
can :manage, Membership
|
||||||
|
|
||||||
cannot :change_role, Membership do |membership|
|
cannot :grant_admin, Membership
|
||||||
|
|
||||||
|
cannot [:update, :destroy], Membership do |membership|
|
||||||
@membership.account_id == membership.account_id || # can not edit myself
|
@membership.account_id == membership.account_id || # can not edit myself
|
||||||
membership.admin? # can not modify an administrator
|
membership.admin? # can not modify an administrator
|
||||||
end
|
end
|
||||||
@ -74,7 +76,7 @@ class Ability
|
|||||||
def setup_admin_permissions!
|
def setup_admin_permissions!
|
||||||
can :manage, :all
|
can :manage, :all
|
||||||
|
|
||||||
cannot :change_role, Membership do |membership|
|
cannot [:update, :destroy], Membership do |membership|
|
||||||
@membership.account_id == membership.account_id # can not edit myself
|
@membership.account_id == membership.account_id # can not edit myself
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -11,6 +11,7 @@ class Membership
|
|||||||
|
|
||||||
## validations ##
|
## validations ##
|
||||||
validates_presence_of :account
|
validates_presence_of :account
|
||||||
|
validate :can_change_role, :if => :role_changed?
|
||||||
|
|
||||||
## callbacks ##
|
## callbacks ##
|
||||||
before_save :define_role
|
before_save :define_role
|
||||||
@ -55,4 +56,18 @@ class Membership
|
|||||||
self.role = Ability::ROLES.include?(role.downcase) ? role.downcase : Ability::ROLES.first
|
self.role = Ability::ROLES.include?(role.downcase) ? role.downcase : Ability::ROLES.first
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Users should not be able to set the role of another user to be higher than
|
||||||
|
# their own. A designer for example should not be able to set another user to
|
||||||
|
# be an administrator
|
||||||
|
def can_change_role
|
||||||
|
current_site = Thread.current[:site]
|
||||||
|
current_membership = current_site.memberships.where(:account_id => Thread.current[:admin].id).first if current_site.present?
|
||||||
|
|
||||||
|
if current_membership.present?
|
||||||
|
# The role cannot be set higher than the current one (we use the index in
|
||||||
|
# the roles array to check role presidence)
|
||||||
|
errors.add(:role, :invalid) if Ability::ROLES.index(role) < Ability::ROLES.index(current_membership.role)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -54,11 +54,14 @@
|
|||||||
|
|
||||||
%em.email= account.email
|
%em.email= account.email
|
||||||
|
|
||||||
- if can?(:change_role, membership)
|
- if can?(:update, membership)
|
||||||
.role
|
.role
|
||||||
%em.editable= t("admin.memberships.roles.#{membership.role}")
|
%em.editable= t("admin.memberships.roles.#{membership.role}")
|
||||||
|
|
||||||
= fm.select :role, Ability::ROLES.collect { |r| [t("admin.memberships.roles.#{r}"), r] }, :include_blank => false
|
- if can?(:grant_admin, membership)
|
||||||
|
= fm.select :role, Ability::ROLES.map { |r| [t("admin.memberships.roles.#{r}"), r] }, :include_blank => false
|
||||||
|
- else
|
||||||
|
= fm.select :role, (Ability::ROLES - ['admin']).map { |r| [t("admin.memberships.roles.#{r}"), r] }, :include_blank => false
|
||||||
|
|
||||||
%span.actions
|
%span.actions
|
||||||
= link_to image_tag('admin/form/icons/trash.png'), admin_membership_url(membership), :class => 'remove first', :confirm =>t('admin.messages.confirm'), :method => :delete
|
= link_to image_tag('admin/form/icons/trash.png'), admin_membership_url(membership), :class => 'remove first', :confirm =>t('admin.messages.confirm'), :method => :delete
|
||||||
@ -73,4 +76,4 @@
|
|||||||
= f.custom_input :robots_txt, :css => 'code full', :with_label => false do
|
= f.custom_input :robots_txt, :css => 'code full', :with_label => false do
|
||||||
= f.label :robots_txt
|
= f.label :robots_txt
|
||||||
%code{ :class => 'html' }
|
%code{ :class => 'html' }
|
||||||
= f.text_area :robots_txt, :class => 'small'
|
= f.text_area :robots_txt, :class => 'small'
|
||||||
|
@ -36,6 +36,7 @@ Background:
|
|||||||
And I should not see the role dropdown on myself
|
And I should not see the role dropdown on myself
|
||||||
And I should not see the role dropdown on the "admin"
|
And I should not see the role dropdown on the "admin"
|
||||||
And I should see the role dropdown on the "author"
|
And I should see the role dropdown on the "author"
|
||||||
|
And I should not the role dropdown on the "author" without the "Administrator" option
|
||||||
And I should not see delete on the "admin"
|
And I should not see delete on the "admin"
|
||||||
And I should not see delete on myself
|
And I should not see delete on myself
|
||||||
And I should see delete on the "author"
|
And I should see delete on the "author"
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
Then /^I should see the role dropdown on the "([^"]*)"$/ do |user|
|
Then /^I should see the role dropdown on the "([^"]*)"$/ do |user|
|
||||||
find(:css, "li.membership[data-role=#{user}] select").text.should == 'AdministratorDesignerAuthor'
|
find(:css, "li.membership[data-role=#{user}] select").should be_present
|
||||||
|
end
|
||||||
|
|
||||||
|
Then /^I should not the role dropdown on the "([^"]*)" without the "([^"]*)" option$/ do |user, option|
|
||||||
|
find(:css, "li.membership[data-role=#{user}] select").text.should_not include option
|
||||||
end
|
end
|
||||||
|
|
||||||
Then /^I should see the role dropdown on myself$/ do
|
Then /^I should see the role dropdown on myself$/ do
|
||||||
@ -33,3 +37,7 @@ end
|
|||||||
Then /^I should not see any delete buttons$/ do
|
Then /^I should not see any delete buttons$/ do
|
||||||
page.has_css?('li.membership .actions a.remove').should be_false
|
page.has_css?('li.membership .actions a.remove').should be_false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
When /^I select the "([^"]*)" role for the "author" user/ do |role|
|
||||||
|
Given %{I select "#{role}" from "site[memberships_attributes][2][role]"}
|
||||||
|
end
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
# - I have the site: "some site" set up with name: "Something", domain: "test2"
|
# - I have the site: "some site" set up with name: "Something", domain: "test2"
|
||||||
#
|
#
|
||||||
Given /^I have the site: "([^"]*)" set up(?: with #{capture_fields})?$/ do |site_factory, fields|
|
Given /^I have the site: "([^"]*)" set up(?: with #{capture_fields})?$/ do |site_factory, fields|
|
||||||
|
Thread.current[:site] = nil
|
||||||
@site = FactoryGirl.create(site_factory, parse_fields(fields))
|
@site = FactoryGirl.create(site_factory, parse_fields(fields))
|
||||||
@site.should_not be_nil
|
@site.should_not be_nil
|
||||||
|
|
||||||
|
@ -22,6 +22,9 @@ module HtmlSelectorsHelpers
|
|||||||
|
|
||||||
when "the has many selector"
|
when "the has many selector"
|
||||||
".has-many-selector ul li.template"
|
".has-many-selector ul li.template"
|
||||||
|
|
||||||
|
when 'the role'
|
||||||
|
'.role'
|
||||||
|
|
||||||
# Add more mappings here.
|
# Add more mappings here.
|
||||||
# Here is an example that pulls values out of the Regexp:
|
# Here is an example that pulls values out of the Regexp:
|
||||||
|
@ -125,6 +125,15 @@ describe Ability do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'granting admin' do
|
||||||
|
it 'should allow only admins to grant admin role' do
|
||||||
|
should allow_permission_from :grant_admin, @admin
|
||||||
|
should_not allow_permission_from :grant_admin, @designer
|
||||||
|
should_not allow_permission_from :grant_admin, @author
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user