Merge branch 'master' of git://github.com/locomotivecms/engine

This commit is contained in:
Sharagoz 2011-10-08 21:17:03 +02:00
commit 35e2fd2d57
21 changed files with 169 additions and 57 deletions

View File

@ -11,7 +11,7 @@ gem 'devise', '1.3.4'
gem 'devise_bushido_authenticatable', '1.0.0.alpha10', :require => 'devise_cas_authenticatable'
gem 'mongoid', '~> 2.0.2'
gem 'bson_ext', '~> 1.3.0'
gem 'bson_ext', '~> 1.4.0'
gem 'locomotive_mongoid_acts_as_tree', '0.1.5.7', :require => 'mongoid_acts_as_tree'
gem 'will_paginate', '~> 3.0.0'
@ -32,7 +32,7 @@ gem 'fog', '0.8.2'
gem 'mimetype-fu'
gem 'actionmailer-with-request', :require => 'actionmailer_with_request'
gem 'heroku', '1.19.1'
gem 'httparty', '>= 0.6.1'
gem 'httparty', '0.7.8'
gem 'RedCloth', '4.2.8'
gem 'delayed_job', '2.1.4'
gem 'delayed_job_mongoid', '1.0.2'

View File

@ -7,7 +7,7 @@ GEM
Platform (0.4.0)
RedCloth (4.2.8)
SystemTimer (1.2.3)
ZenTest (4.6.1)
ZenTest (4.6.2)
abstract (1.0.0)
actionmailer (3.0.10)
actionpack (= 3.0.10)
@ -42,8 +42,8 @@ GEM
autotest (4.4.6)
ZenTest (>= 4.4.1)
bcrypt-ruby (2.1.4)
bson (1.3.1)
bson_ext (1.3.1)
bson (1.4.0)
bson_ext (1.4.0)
builder (2.1.2)
bushido (0.0.35)
highline (>= 1.6.1)
@ -53,7 +53,7 @@ GEM
bushido_stub (0.0.3)
activesupport (>= 3.0.7)
cancan (1.6.5)
capybara (1.0.1)
capybara (1.1.1)
mime-types (>= 1.16)
nokogiri (>= 1.3.3)
rack (>= 1.0.0)
@ -62,20 +62,20 @@ GEM
xpath (~> 0.1.4)
carrierwave (0.5.6)
activesupport (~> 3.0)
cells (3.6.5)
cells (3.6.6)
actionpack (~> 3.0)
railties (~> 3.0)
childprocess (0.2.1)
childprocess (0.2.2)
ffi (~> 1.0.6)
columnize (0.3.4)
configuration (1.3.1)
crack (0.1.8)
cucumber (1.0.2)
cucumber (1.0.6)
builder (>= 2.1.2)
diff-lcs (>= 1.1.2)
gherkin (~> 2.4.5)
gherkin (~> 2.4.18)
json (>= 1.4.6)
term-ansicolor (>= 1.0.5)
term-ansicolor (>= 1.0.6)
cucumber-rails (1.0.2)
capybara (>= 1.0.0)
cucumber (~> 1.0.0)
@ -99,15 +99,16 @@ GEM
devise
devise (>= 1.0.6)
rubycas-client (>= 2.2.1)
diff-lcs (1.1.2)
dragonfly (0.9.5)
diff-lcs (1.1.3)
dragonfly (0.9.8)
rack
erubis (2.6.6)
abstract (>= 1.0.0)
excon (0.6.5)
factory_girl (2.0.4)
factory_girl_rails (1.1.0)
factory_girl (~> 2.0.0)
excon (0.6.6)
factory_girl (2.1.2)
activesupport
factory_girl_rails (1.2.0)
factory_girl (~> 2.1.0)
railties (>= 3.0.0)
ffi (1.0.9)
fog (0.8.2)
@ -119,12 +120,12 @@ GEM
net-ssh (>= 2.1.3)
nokogiri (>= 1.4.4)
ruby-hmac
formatador (0.2.0)
formatador (0.2.1)
formtastic (1.2.4)
actionpack (>= 2.3.7)
activesupport (>= 2.3.7)
i18n (~> 0.4)
gherkin (2.4.6)
gherkin (2.4.21)
json (>= 1.4.6)
growl-glue (1.0.7)
haml (3.1.2)
@ -132,7 +133,7 @@ GEM
heroku (1.19.1)
activesupport (>= 2.1.0)
launchy (~> 0.3.2)
rest-client (>= 1.4.0, < 1.7.0)
rest-client (< 1.7.0, >= 1.4.0)
highline (1.6.2)
httparty (0.7.8)
crack (= 0.1.8)
@ -142,8 +143,8 @@ GEM
responders (~> 0.6.0)
jammit (0.6.3)
yui-compressor (>= 0.9.3)
json (1.5.3)
json_pure (1.5.3)
json (1.6.1)
json_pure (1.6.1)
kgio (2.6.0)
launchy (0.3.7)
configuration (>= 0.0.5)
@ -167,23 +168,23 @@ GEM
mimemagic (0.1.8)
mimetype-fu (0.1.2)
mocha (0.9.12)
mongo (1.3.1)
bson (>= 1.3.1)
mongo (1.4.0)
bson (= 1.4.0)
mongoid (2.0.2)
activemodel (~> 3.0)
mongo (~> 1.3)
tzinfo (~> 0.3.22)
net-ssh (2.1.4)
net-ssh (2.2.1)
nokogiri (1.5.0)
open4 (1.1.0)
orm_adapter (0.0.5)
pickle (0.4.8)
pickle (0.4.10)
cucumber (>= 0.8)
rake
polyglot (0.3.2)
proxies (0.2.1)
rack (1.2.3)
rack-cache (1.0.2)
rack (1.2.4)
rack-cache (1.1)
rack (>= 0.4)
rack-mount (0.6.14)
rack (>= 1.0.0)
@ -207,7 +208,7 @@ GEM
rake (0.9.2)
rdoc (3.9.4)
responders (0.6.4)
rest-client (1.6.3)
rest-client (1.6.7)
mime-types (>= 1.16)
rmagick (2.12.2)
rspec (2.6.0)
@ -249,9 +250,9 @@ GEM
s3 (0.3.8)
proxies (~> 0.2.0)
sanitize (2.0.3)
nokogiri (>= 1.4.4, < 1.6)
nokogiri (< 1.6, >= 1.4.4)
sass (3.1.2)
selenium-webdriver (2.4.0)
selenium-webdriver (2.7.0)
childprocess (>= 0.2.1)
ffi (>= 1.0.7)
json_pure
@ -263,13 +264,13 @@ GEM
polyglot
polyglot (>= 0.3.1)
tzinfo (0.3.29)
unicorn (4.0.1)
unicorn (4.1.1)
kgio (~> 2.4)
rack
raindrops (~> 0.6)
warden (1.0.5)
rack (>= 1.0)
will_paginate (3.0.0)
will_paginate (3.0.2)
xpath (0.1.4)
nokogiri (~> 1.3)
yui-compressor (0.9.6)
@ -284,7 +285,7 @@ DEPENDENCIES
ZenTest
actionmailer-with-request
autotest
bson_ext (~> 1.3.0)
bson_ext (~> 1.4.0)
bushido (= 0.0.35)
bushido_stub (= 0.0.3)
cancan
@ -307,7 +308,7 @@ DEPENDENCIES
haml (= 3.1.2)
heroku (= 1.19.1)
highline
httparty (>= 0.6.1)
httparty (= 0.7.8)
inherited_resources (~> 1.1.2)
launchy
linecache (= 0.43)

View File

@ -15,6 +15,8 @@ module Admin
before_filter :set_locale
before_filter :set_current_thread_variables
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
@ -42,6 +44,11 @@ module Admin
protected
def set_current_thread_variables
Thread.current[:admin] = current_admin
Thread.current[:site] = current_site
end
def current_ability
@current_ability ||= Ability.new(current_admin, current_site)
end

View File

@ -65,7 +65,9 @@ class Ability
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.admin? # can not modify an administrator
end
@ -74,7 +76,7 @@ class Ability
def setup_admin_permissions!
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
end
end

View File

@ -47,12 +47,12 @@ class Account
def remove_memberships!
self.sites.each do |site|
site.memberships.delete_if { |m| m.account_id == self._id }
membership = site.memberships.where(:account_id => self._id).first
if site.admin_memberships.empty?
if site.admin_memberships.size == 1 && membership.admin?
raise I18n.t('errors.messages.needs_admin_account')
else
site.save
membership.destroy
end
end
end

View File

@ -50,6 +50,14 @@ class ContentInstance
def visible?
self._visible || self._visible.nil?
end
def next
content_type.contents.where(:_position_in_list => _position_in_list + 1).first()
end
def previous
content_type.contents.where(:_position_in_list => _position_in_list - 1).first()
end
def errors_to_hash
Hash.new.replace(self.errors)

View File

@ -11,6 +11,7 @@ class Membership
## validations ##
validates_presence_of :account
validate :can_change_role, :if => :role_changed?
## callbacks ##
before_save :define_role
@ -55,4 +56,18 @@ class Membership
self.role = Ability::ROLES.include?(role.downcase) ? role.downcase : Ability::ROLES.first
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

View File

@ -54,11 +54,14 @@
%em.email= account.email
- if can?(:change_role, membership)
- if can?(:update, 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
= 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.label :robots_txt
%code{ :class => 'html' }
= f.text_area :robots_txt, :class => 'small'
= f.text_area :robots_txt, :class => 'small'

View File

@ -29,7 +29,7 @@ ru:
title: "Страница не найдена"
body: "Содержимое страницы 404"
other:
body: "{% расширяет 'parent' %}"
body: "{% extends 'parent' %}"
mongoid:
attributes:

View File

@ -35,7 +35,7 @@ Background:
And I should see "Access points"
And I should not see the role dropdown on myself
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" without the "Administrator" option
And I should not see delete on the "admin"
And I should not see delete on myself
And I should see delete on the "author"

View File

@ -1,5 +1,9 @@
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 see 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
Then /^I should see the role dropdown on myself$/ do
@ -33,3 +37,7 @@ end
Then /^I should not see any delete buttons$/ do
page.has_css?('li.membership .actions a.remove').should be_false
end
When /^I select the "([^"]*)" role for the "author" user/ do |role|
Given %{I select "#{role}" from "site[memberships_attributes][2][role]"}
end

View File

@ -5,6 +5,7 @@
# - 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|
Thread.current[:site] = nil
@site = FactoryGirl.create(site_factory, parse_fields(fields))
@site.should_not be_nil

View File

@ -22,6 +22,9 @@ module HtmlSelectorsHelpers
when "the has many selector"
".has-many-selector ul li.template"
when 'the role'
'.role'
# Add more mappings here.
# Here is an example that pulls values out of the Regexp:

View File

@ -210,7 +210,7 @@ module Locomotive
end
def set_highlighted_field_name(content_type)
field = content_type.content_custom_fields.detect { |f| f._alias == content_type.highlighted_field_name }
field = content_type.content_custom_fields.detect { |f| f._alias == content_type.highlighted_field_name.to_s }
content_type.highlighted_field_name = field._name if field
end

View File

@ -8,6 +8,32 @@ module Locomotive
def _id
self._source._id.to_s
end
# Returns the next content for the parent content type.
# If no content is found, nil is returned.
#
# Usage:
#
# {% if article.next %}
# <a href="/articles/{{ article.next._permalink }}">Read next article</a>
# {% endif %}
#
def next
self._source.next.to_liquid
end
# Returns the previous content for the parent content type.
# If no content is found, nil is returned.
#
# Usage:
#
# {% if article.previous %}
# <a href="/articles/{{ article.previous._permalink }}">Read previous article</a>
# {% endif %}
#
def previous
self._source.previous.to_liquid
end
def before_method(meth)
return '' if self._source.nil?

View File

@ -23,9 +23,9 @@ module Locomotive
def decode(attributes, context)
attributes.each_pair do |key, value|
attributes[key] = (case value
when /true|false/ then value == 'true'
when /[0-9]+/ then value.to_i
when /'(\S+)'/ then $1
when /^true|false$/i then value == 'true'
when /^[0-9]+$/ then value.to_i
when /^["|'](.+)["|']$/ then $1.gsub(/^["|']/, '').gsub(/["|']$/, '')
else
context[value]
end)

View File

@ -17,12 +17,12 @@ Gem::Specification.new do |s|
s.required_rubygems_version = '>= 1.3.6'
s.rubyforge_project = 'nowarning'
s.add_dependency 'rails', '>= 3.0.10'
s.add_dependency 'rails', '~> 3.0.10'
s.add_dependency 'warden'
s.add_dependency 'devise', '1.3.4'
s.add_dependency 'devise_bushido_authenticatable', '1.0.0.alpha10'
s.add_dependency 'mongoid', '2.0.2'
s.add_dependency 'bson_ext', '~> 1.3.0'
s.add_dependency 'mongoid', '~> 2.0.2'
s.add_dependency 'bson_ext', '~> 1.4.0'
s.add_dependency 'locomotive_mongoid_acts_as_tree', '0.1.5.7'
s.add_dependency 'will_paginate', '~> 3.0.0'
@ -49,7 +49,7 @@ Gem::Specification.new do |s|
s.add_dependency 'fog', '0.8.2'
s.add_dependency 'mimetype-fu'
s.add_dependency 'actionmailer-with-request'
s.add_dependency 'httparty', '>= 0.6.1'
s.add_dependency 'httparty', '0.7.8'
s.add_dependency 'RedCloth', '4.2.8'
s.add_dependency 'delayed_job', '2.1.4'
s.add_dependency 'delayed_job_mongoid', '1.0.2'

Binary file not shown.

View File

@ -125,6 +125,15 @@ describe Ability do
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

View File

@ -47,13 +47,14 @@ describe Account do
end
it 'should also delete memberships' do
Site.any_instance.stubs(:admin_memberships).returns(['junk'])
Site.any_instance.stubs(:admin_memberships).returns(['junk', 'dirt'])
@site_1.memberships.first.expects(:destroy)
@site_2.memberships.first.expects(:destroy)
@account.destroy
@site_1.memberships.should be_empty
@site_2.memberships.should be_empty
end
it 'should raise an exception if account is the only remaining admin' do
@site_1.memberships.first.stubs(:admin?).returns(true)
@site_1.stubs(:admin_memberships).returns(['junk'])
lambda {
@account.destroy

View File

@ -42,6 +42,34 @@ describe ContentInstance do
end
describe "#navigation" do
before(:each) do
%w(first second third).each_with_index do |item,index|
content = build_content({:title => item.to_s})
content._position_in_list = index
instance_variable_set "@#{item}", content
end
end
it 'should find previous item when available' do
@second.previous.custom_field_1.should == "first"
@second.previous._position_in_list.should == 0
end
it 'should find next item when available' do
@second.next.custom_field_1.should == "third"
@second.next._position_in_list.should == 2
end
it 'should return nil when fetching previous item on first in list' do
@first.previous.should == nil
end
it 'should return nil when fetching next item on last in list' do
@third.next.should == nil
end
end
describe '#permalink' do
before(:each) do