Commit 21750a322fecc6d35b6ea3133894efd32cba5d15

Authored by Leandro Santos
2 parents eb5146b3 6e1949cf

Merge branch 'master' into api

Showing 61 changed files with 1280 additions and 66 deletions   Show diff stats
Gemfile
... ... @@ -32,18 +32,17 @@ gem 'rack-contrib'
32 32 # FIXME list here all actual dependencies (i.e. the ones in debian/control),
33 33 # with their GEM names (not the Debian package names)
34 34  
35   -group :assets do
36   - gem 'uglifier', '>= 1.0.3'
37   - gem 'sass-rails'
38   -end
  35 +# asset pipeline
  36 +gem 'uglifier', '>= 1.0.3'
  37 +gem 'sass-rails'
39 38  
40 39 group :production do
41 40 gem 'dalli', '~> 2.7.0'
42 41 end
43 42  
44 43 group :test do
45   - gem 'rspec', '~> 2.10.0'
46   - gem 'rspec-rails', '~> 2.10.1'
  44 + gem 'rspec', '~> 2.14.0'
  45 + gem 'rspec-rails', '~> 2.14.1'
47 46 gem 'mocha', '~> 1.1.0', :require => false
48 47 end
49 48  
... ...
app/controllers/admin/role_controller.rb
... ... @@ -2,7 +2,7 @@ class RoleController < AdminController
2 2 protect 'manage_environment_roles', :environment
3 3  
4 4 def index
5   - @roles = environment.roles.find(:all)
  5 + @roles = environment.roles.find(:all, :conditions => {:profile_id => nil})
6 6 end
7 7  
8 8 def new
... ...
app/controllers/my_profile/profile_members_controller.rb
... ... @@ -58,6 +58,7 @@ class ProfileMembersController < MyProfileController
58 58  
59 59 def change_role
60 60 @roles = Profile::Roles.organization_member_roles(environment.id)
  61 + @custom_roles = profile.custom_roles
61 62 begin
62 63 @member = profile.members.find(params[:id])
63 64 rescue ActiveRecord::RecordNotFound
... ...
app/controllers/my_profile/profile_roles_controller.rb 0 → 100644
... ... @@ -0,0 +1,116 @@
  1 +class ProfileRolesController < MyProfileController
  2 +
  3 + protect 'manage_custom_roles', :profile
  4 +
  5 + def index
  6 + @roles = profile.custom_roles
  7 + end
  8 +
  9 + def new
  10 + @role = Role.new
  11 + end
  12 +
  13 + def create
  14 + @role = Role.new({:name => params[:role][:name], :permissions => params[:role][:permissions], :environment => environment }, :without_protection => true)
  15 + if @role.save
  16 + profile.custom_roles << @role
  17 + redirect_to :action => 'show', :id => @role
  18 + else
  19 + session[:notice] = _('Failed to create role')
  20 + render :action => 'new'
  21 + end
  22 + end
  23 +
  24 + def show
  25 + @role = environment.roles.find(params[:id])
  26 + end
  27 +
  28 + def edit
  29 + @role = environment.roles.find(params[:id])
  30 + end
  31 +
  32 + def assign_role_by_members
  33 + return redirect_to "/" if params[:q].nil? or !request.xhr?
  34 + arg = params[:q].downcase
  35 + result = find_by_contents(:people, environment, profile.members, params[:q])[:results]
  36 + render :text => prepare_to_token_input(result).to_json
  37 + end
  38 +
  39 + def destroy
  40 + @role = environment.roles.find(params[:id])
  41 + @members = profile.members_by_role(@role)
  42 + @roles_list = all_roles(environment, profile)
  43 + @roles_list.delete(@role)
  44 + end
  45 +
  46 + def remove
  47 + @role = environment.roles.find(params[:id])
  48 + @members = profile.members_by_role(@role)
  49 + member_roles = params[:roles] ? environment.roles.find(params[:roles].select{|r|!r.to_i.zero?}) : []
  50 + append_roles(@members, member_roles, profile)
  51 + if @role.destroy
  52 + session[:notice] = _('Role successfuly removed!')
  53 + else
  54 + session[:notice] = _('Failed to remove role!')
  55 + end
  56 + redirect_to :action => 'index'
  57 + end
  58 +
  59 + def update
  60 + @role = environment.roles.find(params[:id])
  61 + if @role.update_attributes(params[:role])
  62 + redirect_to :action => 'show', :id => @role
  63 + else
  64 + session[:notice] = _('Failed to edit role')
  65 + render :action => 'edit'
  66 + end
  67 + end
  68 +
  69 + def assign
  70 + @role = environment.roles.find(params[:id])
  71 + @roles_list = all_roles(environment, profile)
  72 + @roles_list.delete(@role)
  73 + end
  74 +
  75 + def define
  76 + @role = environment.roles.find(params[:id])
  77 + selected_role = params[:selected_role] ? environment.roles.find(params[:selected_role].to_i) : nil
  78 + if params[:assign_role_by].eql? "members"
  79 + members_list = params[:person_id].split(',').collect {|id| environment.profiles.find(id.to_i)}
  80 + members_list.collect{|person| person.add_role(@role, profile)}
  81 + elsif params[:assign_role_by].eql? "roles"
  82 + members = profile.members_by_role(selected_role)
  83 + replace_role(members, selected_role, @role, profile)
  84 + else
  85 + session[:notice] = _("Error")
  86 + end
  87 + redirect_to :action => 'index'
  88 + end
  89 +
  90 + protected
  91 +
  92 + def append_roles(members, roles, profile)
  93 + members.each do |person|
  94 + all_roles = person.find_roles(profile).map(&:role) + roles
  95 + person.define_roles(all_roles, profile)
  96 + end
  97 + end
  98 +
  99 + def all_roles(environment, profile)
  100 + Profile::Roles.organization_member_roles(environment.id) + profile.custom_roles
  101 + end
  102 +
  103 + def replace_roles(members, roles, profile)
  104 + members.each do |person|
  105 + person.define_roles(roles, profile)
  106 + end
  107 + end
  108 +
  109 + def replace_role(members, role, new_role, profile)
  110 + members.each do |person|
  111 + person.remove_role(role, profile)
  112 + person.add_role(new_role, profile)
  113 + end
  114 + end
  115 +
  116 +end
... ...
app/helpers/application_helper.rb
... ... @@ -707,6 +707,24 @@ module ApplicationHelper
707 707 javascript_include_tag script if script
708 708 end
709 709  
  710 + def template_path
  711 + if profile.nil?
  712 + "/designs/templates/#{environment.layout_template}"
  713 + else
  714 + "/designs/templates/#{profile.layout_template}"
  715 + end
  716 + end
  717 +
  718 + def template_javascript_src
  719 + script = File.join template_path, '/javascripts/template.js'
  720 + script if File.exists? File.join(Rails.root, 'public', script)
  721 + end
  722 +
  723 + def templete_javascript_ng
  724 + script = template_javascript_src
  725 + javascript_include_tag script if script
  726 + end
  727 +
710 728 def file_field_or_thumbnail(label, image, i)
711 729 display_form_field label, (
712 730 render :partial => (image && image.valid? ? 'shared/show_thumbnail' : 'shared/change_image'),
... ...
app/helpers/layout_helper.rb
... ... @@ -38,6 +38,8 @@ module LayoutHelper
38 38 output += theme_javascript_ng.to_s
39 39 output += javascript_tag 'render_all_jquery_ui_widgets()'
40 40  
  41 + output += templete_javascript_ng.to_s
  42 +
41 43 output
42 44 end
43 45  
... ... @@ -70,11 +72,7 @@ module LayoutHelper
70 72 end
71 73  
72 74 def template_stylesheet_path
73   - if profile.nil?
74   - "/designs/templates/#{environment.layout_template}/stylesheets/style.css"
75   - else
76   - "/designs/templates/#{profile.layout_template}/stylesheets/style.css"
77   - end
  75 + File.join template_path, "/stylesheets/style.css"
78 76 end
79 77  
80 78  
... ...
app/models/environment.rb
... ... @@ -19,6 +19,8 @@ class Environment &lt; ActiveRecord::Base
19 19 filename
20 20 end
21 21  
  22 + NUMBER_OF_BOXES = 4
  23 +
22 24 PERMISSIONS['Environment'] = {
23 25 'view_environment_admin_panel' => N_('View environment admin panel'),
24 26 'edit_environment_features' => N_('Edit environment features'),
... ... @@ -172,7 +174,7 @@ class Environment &lt; ActiveRecord::Base
172 174 acts_as_having_boxes
173 175  
174 176 after_create do |env|
175   - 3.times do
  177 + NUMBER_OF_BOXES.times do
176 178 env.boxes << Box.new
177 179 end
178 180  
... ... @@ -737,8 +739,8 @@ class Environment &lt; ActiveRecord::Base
737 739 end
738 740  
739 741 def is_default_template?(template)
740   - is_default = template == community_default_template
741   - is_default = is_default || template == person_default_template
  742 + is_default = template == community_default_template
  743 + is_default = is_default || template == person_default_template
742 744 is_default = is_default || template == enterprise_default_template
743 745 is_default
744 746 end
... ...
app/models/organization.rb
... ... @@ -36,6 +36,8 @@ class Organization &lt; Profile
36 36  
37 37 has_many :mailings, :class_name => 'OrganizationMailing', :foreign_key => :source_id, :as => 'source'
38 38  
  39 + has_many :custom_roles, :class_name => 'Role', :foreign_key => :profile_id
  40 +
39 41 scope :more_popular, :order => 'members_count DESC'
40 42  
41 43 validate :presence_of_required_fieds, :unless => :is_template
... ...
app/models/profile.rb
... ... @@ -22,6 +22,8 @@ class Profile &lt; ActiveRecord::Base
22 22 :display => %w[compact]
23 23 }
24 24  
  25 + NUMBER_OF_BOXES = 4
  26 +
25 27 def self.default_search_display
26 28 'compact'
27 29 end
... ... @@ -43,7 +45,7 @@ class Profile &lt; ActiveRecord::Base
43 45 find_role('editor', env_id)
44 46 end
45 47 def self.organization_member_roles(env_id)
46   - all_roles(env_id).select{ |r| r.key.match(/^profile_/) unless r.key.blank? }
  48 + all_roles(env_id).select{ |r| r.key.match(/^profile_/) unless r.key.blank? || !r.profile_id.nil?}
47 49 end
48 50 def self.all_roles(env_id)
49 51 Role.all :conditions => { :environment_id => env_id }
... ... @@ -75,6 +77,7 @@ class Profile &lt; ActiveRecord::Base
75 77 'publish_content' => N_('Publish content'),
76 78 'invite_members' => N_('Invite members'),
77 79 'send_mail_to_members' => N_('Send e-Mail to members'),
  80 + 'manage_custom_roles' => N_('Manage custom roles'),
78 81 }
79 82  
80 83 acts_as_accessible
... ... @@ -371,7 +374,7 @@ class Profile &lt; ActiveRecord::Base
371 374 if template
372 375 apply_template(template, :copy_articles => false)
373 376 else
374   - 3.times do
  377 + NUMBER_OF_BOXES.times do
375 378 self.boxes << Box.new
376 379 end
377 380  
... ... @@ -414,6 +417,7 @@ class Profile &lt; ActiveRecord::Base
414 417 alias_method_chain :template, :default
415 418  
416 419 def apply_template(template, options = {:copy_articles => true})
  420 + self.template = template
417 421 copy_blocks_from(template)
418 422 copy_articles_from(template) if options[:copy_articles]
419 423 self.apply_type_specific_template(template)
... ...
app/views/blocks/profile_info_actions/_join_leave_community.html.erb
1   -<div class='join-leave-button'>
  1 +<div class='join-leave-button require-login-popup'>
2 2 <% if logged_in? %>
3 3 <% if profile.members.include?(user) %>
4 4 <%= button(:delete, content_tag('span', _('Leave community')), profile.leave_url,
... ...
app/views/profile_editor/index.html.erb
... ... @@ -28,6 +28,8 @@
28 28  
29 29 <%= control_panel_button(_('Manage Content'), 'cms', :controller => 'cms') %>
30 30  
  31 + <%= control_panel_button(_('Manage Roles'), 'roles', :controller => 'profile_roles') %>
  32 +
31 33 <% unless profile.enterprise? %>
32 34 <%= case profile.blogs.count
33 35 when 0
... ...
app/views/profile_members/change_role.html.erb
1 1 <h3> <%= _('Changing role of %s') % @member.name %> </h3>
2 2  
3 3 <%= labelled_form_for :member, :url => {:action => 'update_roles'} do |f| %>
4   -
5   - <%= _('Roles:') %> <br>
  4 +
  5 + <h4><%= _('Roles:') %></h4>
6 6 <% @roles.each do |r| %>
7 7 <%= labelled_check_box(r.name, 'roles[]', r.id, @associations.map(&:role).include?(r) ) %><br/>
8 8 <ul class="role-permissions">
... ... @@ -11,6 +11,17 @@
11 11 <% end %>
12 12 </ul>
13 13 <% end %>
  14 + <% unless @custom_roles.empty? %>
  15 + <h4><%= _('Custom Roles:') %></h4>
  16 + <% @custom_roles.each do |r| %>
  17 + <%= labelled_check_box(r.name, 'roles[]', r.id, @associations.map(&:role).include?(r) ) %><br/>
  18 + <ul class="role-permissions">
  19 + <% r.permissions.each do |p| %>
  20 + <li> <%= permission_name(p) %> </li>
  21 + <% end %>
  22 + </ul>
  23 + <% end %>
  24 + <% end %>
14 25 <%= hidden_field_tag 'person', @member.id %>
15 26  
16 27 <% button_bar do %>
... ...
app/views/profile_roles/_form.html.erb 0 → 100644
... ... @@ -0,0 +1,22 @@
  1 +<%= error_messages_for :role %>
  2 +
  3 +<%= labelled_form_for :role, :url => (mode == :edit) ? {:action => 'update', :id => role} : {:action => 'create'} do |f| %>
  4 +
  5 + <%= required_fields_message %>
  6 +
  7 + <%= required f.text_field(:name) %>
  8 +
  9 + <% permissions.each do |key| %>
  10 + <div class="permissions <%= key.downcase %>">
  11 + <h4><%= _('%s Permissions:' % key) %></h4>
  12 + <% ActiveRecord::Base::PERMISSIONS[key].keys.each do |p| %>
  13 + <%= check_box_tag("role[permissions][]", p, role.has_permission?(p), { :id => p }) %>
  14 + <%= content_tag(:label, permission_name(p), { :for => p }) %><br/>
  15 + <% end %>
  16 + </div>
  17 + <% end %>
  18 +
  19 + <% button_bar do %>
  20 + <%= submit_button('save', (mode == :edit) ? _('Save changes') : _('Create role'), :cancel => {:action => 'index'} ) %>
  21 + <% end %>
  22 +<% end %>
... ...
app/views/profile_roles/assign.html.erb 0 → 100644
... ... @@ -0,0 +1,35 @@
  1 +<%= javascript_include_tag('assign_role.js') %>
  2 +
  3 +<h1> <%= _("Assign #{@role.name}") %> </h1>
  4 +
  5 +
  6 +<%= labelled_form_for :role, :url => { :action => 'define', :id => @role.id } do |f| %>
  7 +
  8 + <h2>
  9 + <%= _("Assign role by:") %>
  10 + </h2>
  11 + <p>
  12 + <%= labelled_radio_button _("Members"), :assign_role_by, "members", true, :id => "assign_role_by_members", :class => "assign_role_by" %>
  13 + &nbsp;
  14 + <%= labelled_radio_button _("Roles"), :assign_role_by, "roles", false, :id => "assign_role_by_roles", :class => "assign_role_by" %>
  15 + </p>
  16 + <div class="assign_by_members">
  17 + <%=token_input_field_tag(:person_id, 'search-profile-members', {:action => 'assign_role_by_members'},
  18 + {:focus => false, :hint_text => _('Select members to assign the role')}) %>
  19 +
  20 + <% button_bar do %>
  21 + <%= submit_button(:forward, _("Confirm")) %>
  22 + <% end %>
  23 + </div>
  24 + <div class="assign_by_roles" style="display: none;">
  25 + <h6>
  26 + <%= _("Replace role: ") %>
  27 + </h6>
  28 + <% @roles_list.each do |role| %>
  29 + <%= labelled_radio_button role.name , :selected_role, role.id , false, :class => "selected_role" %> <br>
  30 + <% end %>
  31 + <% button_bar do %>
  32 + <%= submit_button('save',_('Confirm'), :cancel => {:action => 'index'} ) %>
  33 + <% end %>
  34 + </div>
  35 +<% end %>
... ...
app/views/profile_roles/destroy.html.erb 0 → 100644
... ... @@ -0,0 +1,23 @@
  1 +<h1> <%= _("Deleting #{@role.name}") %> </h1>
  2 +
  3 +<% if @members.nil? || @members.empty? %>
  4 + <p><%= _('This role is not being currently used.')%></p>
  5 + <p><%= _('Are you sure you want to delete this role?') %></p>
  6 +
  7 + <% button_bar do %>
  8 + <%= button(:remove, _('Yes, I am sure'), {:action => 'remove', :id => @role.id}, :method => :post) %>
  9 + <%= button(:cancel, _('No, I gave up'), {:action => 'index'}) %>
  10 + <% end %>
  11 +<% else %>
  12 + <p><%= _('There are members currently using this role.')%></p>
  13 + <p><%= _('To which role do you want to change them?') %></p>
  14 + <%= labelled_form_for :role, :url => { :action => 'remove', :id => @role.id } do |f| %>
  15 + <% @roles_list.each do |role| %>
  16 + <%= check_box_tag("roles[]", role.id, false ,{:id => role.key}) %>
  17 + <%= content_tag(:label, role.name, { :for => role.key }) %><br/>
  18 + <% end %>
  19 + <% button_bar do %>
  20 + <%= submit_button('save',_('Delete role'), :cancel => {:action => 'index'} ) %>
  21 + <% end %>
  22 + <% end %>
  23 +<% end %>
... ...
app/views/profile_roles/edit.html.erb 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +<h1> <%= _("Editing #{@role.name}") %> </h1>
  2 +
  3 +<%= render :partial => 'form', :locals => { :mode => :edit, :role => @role, :permissions => [@role.kind] } %>
... ...
app/views/profile_roles/index.html.erb 0 → 100644
... ... @@ -0,0 +1,27 @@
  1 +<h1><%= _('Manage user roles') %></h1>
  2 +
  3 +<table>
  4 + <tr>
  5 + <th><%= _('Role') %></th>
  6 + <th><%= _('Actions') %></th>
  7 + </tr>
  8 + <% @roles.each do |role| %>
  9 + <tr>
  10 + <td>
  11 + <%= link_to role.name, :action => 'show', :id => role %>
  12 + </td>
  13 + <td>
  14 + <div style="text-align: center;">
  15 + <%= button_without_text :edit, _('Edit'), :action => 'edit', :id => role %>
  16 + <%= button_without_text :delete, _('Delete'), :action => 'destroy', :id => role %>
  17 + <%= button_without_text 'vertical-toggle', _('Assign'), :action => 'assign', :id => role %>
  18 + </div>
  19 + </td>
  20 + </tr>
  21 + <% end %>
  22 +</table>
  23 +
  24 +<% button_bar do %>
  25 + <%= button :add, _('Create a new role'), :action => 'new' %>
  26 + <%= button :back, _('Back to control panel'), :controller => 'profile_editor' %>
  27 +<% end %>
... ...
app/views/profile_roles/new.html.erb 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +<h1> <%= _("Create a new role") %> </h1>
  2 +
  3 +<%= render :partial => 'form', :locals => { :mode => :create, :role => @role, :permissions => ['Profile'] } %>
... ...
app/views/profile_roles/show.html.erb 0 → 100644
... ... @@ -0,0 +1,13 @@
  1 +<h1> <%= _(@role.name) %></h1>
  2 +
  3 +<h3> <%= _('Permissions') %> </h3>
  4 +<ul>
  5 + <% @role.permissions.each do |p| %>
  6 + <li> <%= permission_name(p) %> </li>
  7 + <% end %>
  8 +</ul>
  9 +
  10 +<% button_bar do %>
  11 + <%= button :edit, _('Edit'), :action => 'edit', :id => @role %>
  12 + <%= button :back, _('Back to roles management'), :action => 'index' %>
  13 +<% end %>
... ...
app/views/tasks/_add_member_accept_details.html.erb
1 1 <%= content = _("Roles:")+"<br />"
2   -roles = Profile::Roles.organization_member_roles(task.target.environment.id)
  2 +roles = Profile::Roles.organization_member_roles(task.target.environment.id) + profile.custom_roles
3 3 roles.each do |role|
4 4 content += labelled_check_box(role.name, "tasks[#{task.id}][task][roles][]", role.id, false)+"<br />"
5 5 end
6 6 content_tag('p', content, :class => 'member-classify-suggestion')
7 7 %>
8   -
... ...
config/environments/development.rb
... ... @@ -35,4 +35,8 @@ Noosfero::Application.configure do
35 35 config.assets.debug = true
36 36  
37 37 config.consider_all_requests_local = true
  38 +
  39 + # send emails to /tmp/mails
  40 + config.action_mailer.delivery_method = :file
  41 +
38 42 end
... ...
db/migrate/20150203143051_add_reference_to_role.rb 0 → 100644
... ... @@ -0,0 +1,8 @@
  1 +class AddReferenceToRole < ActiveRecord::Migration
  2 + def self.up
  3 + add_column :roles, :profile_id, :integer
  4 + end
  5 + def self.down
  6 + remove_column :roles , :profile_id
  7 + end
  8 +end
... ...
db/migrate/20150210143723_add_custom_roles_permission_to_admin_roles.rb 0 → 100644
... ... @@ -0,0 +1,18 @@
  1 +class AddCustomRolesPermissionToAdminRoles < ActiveRecord::Migration
  2 + def self.up
  3 + environment_admin = Role.find_by_key("environment_administrator")
  4 + profile_admin = Role.find_by_key("profile_admin")
  5 + environment_admin.permissions.append("manage_custom_roles")
  6 + profile_admin.permissions.append("manage_custom_roles")
  7 + environment_admin.save!
  8 + profile_admin.save!
  9 + end
  10 + def self.down
  11 + environment_admin = Role.find_by_key("environment_administrator")
  12 + profile_admin = Role.find_by_key("profile_admin")
  13 + environment_admin.permissions.delete("manage_custom_roles")
  14 + profile_admin.permissions.delete("manage_custom_roles")
  15 + environment_admin.save!
  16 + profile_admin.save!
  17 + end
  18 +end
... ...
db/migrate/20150423144533_add_new_box_to_every_environment_and_profile.rb 0 → 100644
... ... @@ -0,0 +1,15 @@
  1 +class AddNewBoxToEveryEnvironmentAndProfile < ActiveRecord::Migration
  2 + def up
  3 + Environment.find_each do |env|
  4 + env.boxes << Box.new if env.boxes.count < 4
  5 + end
  6 +
  7 + Profile.find_each do |profile|
  8 + profile.boxes << Box.new if profile.boxes.count < 4
  9 + end
  10 + end
  11 +
  12 + def down
  13 + say "this migration can't be reverted"
  14 + end
  15 +end
... ...
db/schema.rb
... ... @@ -593,6 +593,7 @@ ActiveRecord::Schema.define(:version =&gt; 20150408231524) do
593 593 t.boolean "system", :default => false
594 594 t.text "permissions"
595 595 t.integer "environment_id"
  596 + t.integer "profile_id"
596 597 end
597 598  
598 599 create_table "scraps", :force => true do |t|
... ...
debian/changelog
  1 +noosfero (1.2~0) UNRELEASED; urgency=medium
  2 +
  3 + * Temporary version in heavy development
  4 +
  5 + -- Antonio Terceiro <terceiro@debian.org> Fri, 08 May 2015 16:08:18 -0300
  6 +
1 7 noosfero (1.1) wheezy; urgency=low
2 8  
3 9 * Noosfero 1.1 final release
... ...
debian/control
... ... @@ -14,8 +14,8 @@ Build-Depends: cucumber,
14 14 ruby-database-cleaner,
15 15 ruby-gettext,
16 16 ruby-mocha,
17   - ruby-rspec,
18   - ruby-rspec-rails,
  17 + ruby-rspec (>= 2.14),
  18 + ruby-rspec-rails (>= 2.14),
19 19 ruby-selenium-webdriver,
20 20 ruby-sqlite3,
21 21 ruby-tidy,
... ... @@ -59,7 +59,9 @@ Depends: adduser,
59 59 ruby-redcloth,
60 60 ruby-rest-client,
61 61 ruby-rmagick,
  62 + ruby-sass-rails,
62 63 ruby-tzinfo (>= 1.1.0-2~),
  64 + ruby-uglifier,
63 65 ruby-whenever,
64 66 ruby-will-paginate (>= 2.3.12-1~),
65 67 tango-icon-theme,
... ...
features/change_appearance.feature 0 → 100644
... ... @@ -0,0 +1,20 @@
  1 +Feature: Change appearance
  2 + As a user
  3 + I want to change the appearance of my profile page
  4 +
  5 + Background:
  6 + Given the following users
  7 + | login | name |
  8 + | joaosilva | Joao Silva |
  9 +
  10 + Scenario: Change appearance from default(3 boxes) to Left Top and Right(4 boxes)
  11 + Given I am logged in as "joaosilva"
  12 + And I go to joaosilva's control panel
  13 + And I follow "Edit sideboxes"
  14 + And I should not see an element ".box-4"
  15 + And I go to joaosilva's control panel
  16 + And I follow "Edit Appearance"
  17 + And I follow "Left Top and Right"
  18 + And I go to joaosilva's control panel
  19 + And I follow "Edit sideboxes"
  20 + And I should see an element ".box-4"
... ...
features/step_definitions/noosfero_steps.rb
... ... @@ -94,8 +94,8 @@ Given /^the following blocks$/ do |table|
94 94 owner.boxes<< Box.new
95 95 owner.boxes.first.blocks << MainBlock.new
96 96 end
97   - box_id = owner.boxes.last.id
98   - klass.constantize.create!(item.merge(:box_id => box_id))
  97 + box = owner.boxes.where(:position => 3).first
  98 + klass.constantize.create!(item.merge(:box => box))
99 99 end
100 100 end
101 101  
... ...
lib/authenticated_system.rb
... ... @@ -60,7 +60,11 @@ module AuthenticatedSystem
60 60 if logged_in? && authorized?
61 61 true
62 62 else
63   - access_denied
  63 + if params[:require_login_popup]
  64 + render :json => { :require_login_popup => true }
  65 + else
  66 + access_denied
  67 + end
64 68 end
65 69 end
66 70  
... ...
lib/noosfero/version.rb
1 1 module Noosfero
2 2 PROJECT = 'noosfero'
3   - VERSION = '1.1'
  3 + VERSION = '1.2~0'
4 4 end
5 5  
6 6 root = File.expand_path(File.dirname(__FILE__) + '/../..')
... ...
plugins/ldap/lib/ldap_plugin.rb
... ... @@ -18,7 +18,8 @@ class LdapPlugin &lt; Noosfero::Plugin
18 18 # - login received by ldap
19 19 # - params from current context
20 20 # returns = updated person_data hash
21   - def ldap_plugin_set_profile_data(attrs, login, params)
  21 + def ldap_plugin_set_profile_data(attrs, params)
  22 + [attrs, params]
22 23 end
23 24  
24 25 # -> Custom ldap plugin hotspot to update user object
... ... @@ -55,19 +56,22 @@ class LdapPlugin &lt; Noosfero::Plugin
55 56  
56 57 if attrs
57 58 user.login = login
58   - user.email = attrs[:mail]
  59 + user.email = get_email(attrs, login)
59 60 user.name = attrs[:fullname]
60 61 user.password = password
61 62 user.password_confirmation = password
62   - person_data = plugins.dispatch(:ldap_plugin_set_profile_data, attrs, login, context.params)
63   - user.person_data = person_data.blank? ? context.params[:profile_data] : person_data
  63 + user.person_data = plugins.pipeline(:ldap_plugin_set_profile_data, attrs, context.params).last[:profile_data]
64 64 user.activated_at = Time.now.utc
65 65 user.activation_code = nil
66 66  
67 67 ldap = LdapAuthentication.new(context.environment.ldap_plugin_attributes)
68 68 begin
69   - user = nil unless user.save!
70   - plugins.dispatch(:ldap_plugin_update_user, user, attrs)
  69 + if user.save
  70 + user.activate
  71 + plugins.dispatch(:ldap_plugin_update_user, user, attrs)
  72 + else
  73 + user = nil
  74 + end
71 75 rescue
72 76 #User not saved
73 77 end
... ... @@ -90,6 +94,16 @@ class LdapPlugin &lt; Noosfero::Plugin
90 94 user
91 95 end
92 96  
  97 + def get_email(attrs, login)
  98 + return attrs[:mail] unless attrs[:mail].blank?
  99 +
  100 + if attrs[:fullname]
  101 + return attrs[:fullname].to_slug + "@ldap.user"
  102 + else
  103 + return login.to_slug + "@ldap.user"
  104 + end
  105 + end
  106 +
93 107 def login_extra_contents
94 108 proc do
95 109 @person = Person.new(:environment => @environment)
... ...
plugins/require_auth_to_comment/controllers/require_auth_to_comment_plugin_admin_controller.rb 0 → 100644
... ... @@ -0,0 +1,14 @@
  1 +class RequireAuthToCommentPluginAdminController < AdminController
  2 +
  3 + def index
  4 + settings = params[:settings]
  5 + settings ||= {}
  6 + @settings = Noosfero::Plugin::Settings.new(environment, RequireAuthToCommentPlugin, settings)
  7 + if request.post?
  8 + @settings.save!
  9 + session[:notice] = 'Settings succefully saved.'
  10 + redirect_to :action => 'index'
  11 + end
  12 + end
  13 +
  14 +end
... ...
plugins/require_auth_to_comment/lib/require_auth_to_comment_plugin.rb
... ... @@ -21,11 +21,20 @@ class RequireAuthToCommentPlugin &lt; Noosfero::Plugin
21 21 end
22 22  
23 23 def stylesheet?
24   - true
  24 + !display_login_popup?
  25 + end
  26 +
  27 + def display_login_popup?
  28 + settings = Noosfero::Plugin::Settings.new(context.environment, self.class)
  29 + settings.require_type == 'display_login_popup'
  30 + end
  31 +
  32 + def self.require_type_default_setting
  33 + 'hide_button'
25 34 end
26 35  
27 36 def js_files
28   - ['hide_comment_form.js', 'jquery.livequery.min.js']
  37 + ['hide_comment_form.js', 'jquery.livequery.min.js'] + (display_login_popup? ? ['comment_require_login.js'] : [])
29 38 end
30 39  
31 40 def body_beginning
... ...
plugins/require_auth_to_comment/public/comment_require_login.js 0 → 100644
... ... @@ -0,0 +1,8 @@
  1 +(function($) {
  2 + $(window).bind('userDataLoaded', function(event, data) {
  3 + if (!data.login && $('meta[name="profile.allow_unauthenticated_comments"]').length <= 0) {
  4 + $('.display-comment-form').unbind();
  5 + $('.display-comment-form').addClass('require-login-popup');
  6 + }
  7 + });
  8 +})(jQuery);
... ...
plugins/require_auth_to_comment/test/unit/require_auth_to_comment_plugin_test.rb
... ... @@ -5,9 +5,10 @@ class RequireAuthToCommentPluginTest &lt; ActiveSupport::TestCase
5 5 def setup
6 6 @plugin = RequireAuthToCommentPlugin.new
7 7 @comment = Comment.new
  8 + @environment = fast_create(Environment)
8 9 end
9 10  
10   - attr_reader :plugin, :comment
  11 + attr_reader :plugin, :comment, :environment
11 12  
12 13 should 'reject comments for unauthenticated users' do
13 14 plugin.context = logged_in(false)
... ... @@ -29,6 +30,35 @@ class RequireAuthToCommentPluginTest &lt; ActiveSupport::TestCase
29 30 assert !comment.rejected?
30 31 end
31 32  
  33 + should 'the default require type setting be hide_button' do
  34 + assert_equal 'hide_button', plugin.class.require_type_default_setting
  35 + end
  36 +
  37 + should 'display_login_popup? be false by default' do
  38 + context = mock();
  39 + context.expects(:environment).returns(environment)
  40 + plugin.expects(:context).returns(context)
  41 + assert !plugin.display_login_popup?
  42 + end
  43 +
  44 + should 'display_login_popup? be true if require_type is defined as display_login_popup' do
  45 + context = mock();
  46 + context.expects(:environment).returns(environment)
  47 + environment[:settings] = {:require_auth_to_comment_plugin => {:require_type => "display_login_popup"}}
  48 + plugin.expects(:context).returns(context)
  49 + assert plugin.display_login_popup?
  50 + end
  51 +
  52 + should 'not display stylesheet if login popup is active' do
  53 + plugin.expects(:display_login_popup?).returns(true)
  54 + assert !plugin.stylesheet?
  55 + end
  56 +
  57 + should 'display stylesheet if login popup is inactive' do
  58 + plugin.expects(:display_login_popup?).returns(false)
  59 + assert plugin.stylesheet?
  60 + end
  61 +
32 62 protected
33 63  
34 64 def logged_in(boolean)
... ...
plugins/require_auth_to_comment/views/require_auth_to_comment_plugin_admin/index.html.erb 0 → 100644
... ... @@ -0,0 +1,20 @@
  1 +<h1><%= _('Require auth to comment Settings')%></h1>
  2 +
  3 +<%= form_for(:settings) do |f| %>
  4 +
  5 + <div class="require-type">
  6 + <strong>
  7 + <div class="hide-button">
  8 + <%= radio_button(:settings, :require_type, 'hide_button') %> <%= _('Hide button') %>
  9 + </div>
  10 + <div class="display-login-popup">
  11 + <%= radio_button(:settings, :require_type, 'display_login_popup') %> <%= _('Display login popup') %>
  12 + </div>
  13 + </strong>
  14 + </div>
  15 +
  16 + <% button_bar do %>
  17 + <%= submit_button(:save, _('Save'), :cancel => {:controller => 'plugins', :action => 'index'}) %>
  18 + <% end %>
  19 +
  20 +<% end %>
... ...
plugins/vote/public/style.css
1 1 .vote-actions {
2   - position: absolute;
3 2 top: 40px;
4 3 right: 0px;
5 4 }
... ...
plugins/vote/views/vote/_vote.html.erb
... ... @@ -5,7 +5,7 @@ reload_url = url_for(:controller =&gt; &#39;vote_plugin_profile&#39;, :profile =&gt; profile.i
5 5  
6 6 <span id="vote_<%= model %>_<%= target.id %>_<%= vote %>" data-reload_url=<%= reload_url %> class="vote-action action <%= action %>-action">
7 7  
8   - <%= link_to_remote content_tag(:span, count, :class=>'like-action-counter') + content_tag(:span, '', :class=>"action-icon #{action}"), :url => url, :html => {:class => "#{active ? 'like-action-active':''} #{user ? '':'disabled'}"} %>
  8 + <%= link_to content_tag(:span, count, :class=>'like-action-counter') + content_tag(:span, '', :class=>"action-icon #{action}"), url, :class => "#{active ? 'like-action-active':''} #{user ? '':'disabled'} require-login-popup" %>
9 9  
10 10 <% if !voters.blank? %>
11 11 <span class="vote-detail">
... ...
public/designs/templates/lefttopright/config.yml 0 → 100644
... ... @@ -0,0 +1,4 @@
  1 +name: "Top and Side Bars"
  2 +title: "1 max colum at left, 1 min colum at right, 1 top line"
  3 +description: "A template with 1 colum in left, 1 colum in right and 1 line in top"
  4 +number_of_boxes: 4
... ...
public/designs/templates/lefttopright/javascripts/template.js 0 → 100644
... ... @@ -0,0 +1,6 @@
  1 +$(document).ready(function() {
  2 + var box_4_height = $(".box-4").height();
  3 +
  4 + // Make box-2(the most left one) stay align with box-4
  5 + $(".box-2").css("margin-top", "-"+box_4_height+"px");
  6 +});
... ...
public/designs/templates/lefttopright/stylesheets/style.css 0 → 100644
... ... @@ -0,0 +1,42 @@
  1 +#boxes {
  2 + display: table;
  3 + width: 100%;
  4 +}
  5 +
  6 +.box-1 {
  7 + width: 58%;
  8 + float: left;
  9 + margin: 1% 1% 0% 1%;
  10 +}
  11 +
  12 +
  13 +.box-2 {
  14 + position: relative;
  15 + float: left;
  16 + width: 20%;
  17 +}
  18 +
  19 +.box-3 {
  20 + position: relative;
  21 + float: right;
  22 + width: 20%;
  23 + margin-top: 1%;
  24 +}
  25 +
  26 +.box-4 {
  27 + float: left;
  28 + width: 79%;
  29 + margin-left: 21%;
  30 +}
  31 +
  32 +#profile-activity ul,
  33 +#profile-network ul,
  34 +#profile-wall ul {
  35 + width: 460px;
  36 +}
  37 +#profile-activity ul.comment-replies,
  38 +#profile-network ul.comment-replies,
  39 +#profile-wall ul.comment-replies {
  40 + width: auto;
  41 +}
  42 +
... ...
public/designs/templates/lefttopright/thumbnail.png 0 → 100644

3.02 KB

public/designs/templates/lefttopright/thumbnail.svg 0 → 100644
... ... @@ -0,0 +1,434 @@
  1 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2 +<!-- Created with Inkscape (http://www.inkscape.org/) -->
  3 +
  4 +<svg
  5 + xmlns:dc="http://purl.org/dc/elements/1.1/"
  6 + xmlns:cc="http://creativecommons.org/ns#"
  7 + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  8 + xmlns:svg="http://www.w3.org/2000/svg"
  9 + xmlns="http://www.w3.org/2000/svg"
  10 + xmlns:xlink="http://www.w3.org/1999/xlink"
  11 + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
  12 + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
  13 + width="64px"
  14 + height="64px"
  15 + id="svg2383"
  16 + sodipodi:version="0.32"
  17 + inkscape:version="0.48.3.1 r9886"
  18 + sodipodi:docname="thumbnail.svg"
  19 + inkscape:output_extension="org.inkscape.output.svg.inkscape"
  20 + inkscape:export-filename="thumbnail.png"
  21 + inkscape:export-xdpi="90"
  22 + inkscape:export-ydpi="90"
  23 + version="1.1">
  24 + <defs
  25 + id="defs2385">
  26 + <linearGradient
  27 + id="linearGradient3263">
  28 + <stop
  29 + id="stop3265"
  30 + offset="0"
  31 + style="stop-color:#204a87;stop-opacity:1" />
  32 + <stop
  33 + id="stop3267"
  34 + offset="1"
  35 + style="stop-color:#729fcf;stop-opacity:1" />
  36 + </linearGradient>
  37 + <linearGradient
  38 + id="linearGradient3257"
  39 + inkscape:collect="always">
  40 + <stop
  41 + id="stop3259"
  42 + offset="0"
  43 + style="stop-color:#204a87;stop-opacity:1" />
  44 + <stop
  45 + id="stop3261"
  46 + offset="1"
  47 + style="stop-color:#729fcf;stop-opacity:1" />
  48 + </linearGradient>
  49 + <linearGradient
  50 + inkscape:collect="always"
  51 + id="linearGradient3245">
  52 + <stop
  53 + style="stop-color:#204a87;stop-opacity:1"
  54 + offset="0"
  55 + id="stop3247" />
  56 + <stop
  57 + style="stop-color:#729fcf;stop-opacity:1"
  58 + offset="1"
  59 + id="stop3249" />
  60 + </linearGradient>
  61 + <inkscape:perspective
  62 + sodipodi:type="inkscape:persp3d"
  63 + inkscape:vp_x="0 : 32 : 1"
  64 + inkscape:vp_y="0 : 1000 : 0"
  65 + inkscape:vp_z="64 : 32 : 1"
  66 + inkscape:persp3d-origin="32 : 21.333333 : 1"
  67 + id="perspective2391" />
  68 + <filter
  69 + inkscape:collect="always"
  70 + id="filter3241">
  71 + <feGaussianBlur
  72 + inkscape:collect="always"
  73 + stdDeviation="0.9075"
  74 + id="feGaussianBlur3243" />
  75 + </filter>
  76 + <linearGradient
  77 + inkscape:collect="always"
  78 + xlink:href="#linearGradient3245"
  79 + id="linearGradient3251"
  80 + x1="11.5"
  81 + y1="60.5"
  82 + x2="3.5"
  83 + y2="3.5"
  84 + gradientUnits="userSpaceOnUse"
  85 + gradientTransform="translate(2,0)" />
  86 + <linearGradient
  87 + inkscape:collect="always"
  88 + xlink:href="#linearGradient3263"
  89 + id="linearGradient3253"
  90 + x1="49.5"
  91 + y1="60.5"
  92 + x2="23.5"
  93 + y2="3.5"
  94 + gradientUnits="userSpaceOnUse"
  95 + gradientTransform="translate(2,0)" />
  96 + <linearGradient
  97 + inkscape:collect="always"
  98 + xlink:href="#linearGradient3257"
  99 + id="linearGradient3255"
  100 + x1="60.5"
  101 + y1="60.5"
  102 + x2="51.5"
  103 + y2="3.5"
  104 + gradientUnits="userSpaceOnUse" />
  105 + <filter
  106 + color-interpolation-filters="sRGB"
  107 + inkscape:collect="always"
  108 + id="filter3241-2">
  109 + <feGaussianBlur
  110 + inkscape:collect="always"
  111 + stdDeviation="0.9075"
  112 + id="feGaussianBlur3243-4" />
  113 + </filter>
  114 + <linearGradient
  115 + inkscape:collect="always"
  116 + xlink:href="#linearGradient3245-1"
  117 + id="linearGradient3251-0"
  118 + x1="11.5"
  119 + y1="60.5"
  120 + x2="3.5"
  121 + y2="3.5"
  122 + gradientUnits="userSpaceOnUse"
  123 + gradientTransform="translate(249.71429,298.93361)" />
  124 + <linearGradient
  125 + inkscape:collect="always"
  126 + id="linearGradient3245-1">
  127 + <stop
  128 + style="stop-color:#204a87;stop-opacity:1"
  129 + offset="0"
  130 + id="stop3247-6" />
  131 + <stop
  132 + style="stop-color:#729fcf;stop-opacity:1"
  133 + offset="1"
  134 + id="stop3249-5" />
  135 + </linearGradient>
  136 + <filter
  137 + color-interpolation-filters="sRGB"
  138 + inkscape:collect="always"
  139 + id="filter3241-4-8">
  140 + <feGaussianBlur
  141 + inkscape:collect="always"
  142 + stdDeviation="0.9075"
  143 + id="feGaussianBlur3243-0-7" />
  144 + </filter>
  145 + <linearGradient
  146 + inkscape:collect="always"
  147 + xlink:href="#linearGradient3263-5-8"
  148 + id="linearGradient5185"
  149 + gradientUnits="userSpaceOnUse"
  150 + gradientTransform="matrix(1.4160224,0,0,0.76166072,243.22589,313.33388)"
  151 + x1="42.5"
  152 + y1="60.5"
  153 + x2="19.5"
  154 + y2="3.5" />
  155 + <linearGradient
  156 + id="linearGradient3263-5-8">
  157 + <stop
  158 + id="stop3265-4-3"
  159 + offset="0"
  160 + style="stop-color:#204a87;stop-opacity:1" />
  161 + <stop
  162 + id="stop3267-2-4"
  163 + offset="1"
  164 + style="stop-color:#729fcf;stop-opacity:1" />
  165 + </linearGradient>
  166 + <filter
  167 + color-interpolation-filters="sRGB"
  168 + inkscape:collect="always"
  169 + id="filter3241-0">
  170 + <feGaussianBlur
  171 + inkscape:collect="always"
  172 + stdDeviation="0.9075"
  173 + id="feGaussianBlur3243-3" />
  174 + </filter>
  175 + <linearGradient
  176 + inkscape:collect="always"
  177 + xlink:href="#linearGradient3245-7"
  178 + id="linearGradient5168"
  179 + gradientUnits="userSpaceOnUse"
  180 + gradientTransform="matrix(1.0025263,0,0,0.76423683,344.68831,300.13218)"
  181 + x1="11.5"
  182 + y1="60.5"
  183 + x2="3.5"
  184 + y2="3.5" />
  185 + <linearGradient
  186 + inkscape:collect="always"
  187 + id="linearGradient3245-7">
  188 + <stop
  189 + style="stop-color:#204a87;stop-opacity:1"
  190 + offset="0"
  191 + id="stop3247-0" />
  192 + <stop
  193 + style="stop-color:#729fcf;stop-opacity:1"
  194 + offset="1"
  195 + id="stop3249-7" />
  196 + </linearGradient>
  197 + <linearGradient
  198 + inkscape:collect="always"
  199 + xlink:href="#linearGradient3245-70"
  200 + id="linearGradient3251-55"
  201 + x1="11.5"
  202 + y1="60.5"
  203 + x2="3.5"
  204 + y2="3.5"
  205 + gradientUnits="userSpaceOnUse"
  206 + gradientTransform="matrix(1.0025263,0,0,0.76423683,344.68831,300.13218)" />
  207 + <linearGradient
  208 + inkscape:collect="always"
  209 + id="linearGradient3245-70">
  210 + <stop
  211 + style="stop-color:#204a87;stop-opacity:1"
  212 + offset="0"
  213 + id="stop3247-2" />
  214 + <stop
  215 + style="stop-color:#729fcf;stop-opacity:1"
  216 + offset="1"
  217 + id="stop3249-87" />
  218 + </linearGradient>
  219 + <linearGradient
  220 + inkscape:collect="always"
  221 + xlink:href="#linearGradient3245-1"
  222 + id="linearGradient5832"
  223 + gradientUnits="userSpaceOnUse"
  224 + gradientTransform="translate(249.71429,298.93361)"
  225 + x1="11.5"
  226 + y1="60.5"
  227 + x2="3.5"
  228 + y2="3.5" />
  229 + <linearGradient
  230 + inkscape:collect="always"
  231 + xlink:href="#linearGradient3263-5-8"
  232 + id="linearGradient5834"
  233 + gradientUnits="userSpaceOnUse"
  234 + gradientTransform="matrix(1.4160224,0,0,0.76166072,243.22589,313.33388)"
  235 + x1="42.5"
  236 + y1="60.5"
  237 + x2="19.5"
  238 + y2="3.5" />
  239 + <linearGradient
  240 + inkscape:collect="always"
  241 + xlink:href="#linearGradient3245-7"
  242 + id="linearGradient5836"
  243 + gradientUnits="userSpaceOnUse"
  244 + gradientTransform="matrix(1.0025263,0,0,0.76423683,344.68831,300.13218)"
  245 + x1="11.5"
  246 + y1="60.5"
  247 + x2="3.5"
  248 + y2="3.5" />
  249 + <linearGradient
  250 + inkscape:collect="always"
  251 + xlink:href="#linearGradient3245-70"
  252 + id="linearGradient5838"
  253 + gradientUnits="userSpaceOnUse"
  254 + gradientTransform="matrix(1.0025263,0,0,0.76423683,344.68831,300.13218)"
  255 + x1="11.5"
  256 + y1="60.5"
  257 + x2="3.5"
  258 + y2="3.5" />
  259 + </defs>
  260 + <sodipodi:namedview
  261 + id="base"
  262 + pagecolor="#ffffff"
  263 + bordercolor="#666666"
  264 + borderopacity="1.0"
  265 + inkscape:pageopacity="0.0"
  266 + inkscape:pageshadow="2"
  267 + inkscape:zoom="2.5351563"
  268 + inkscape:cx="-16.066434"
  269 + inkscape:cy="0.12147739"
  270 + inkscape:current-layer="layer1"
  271 + showgrid="true"
  272 + inkscape:document-units="px"
  273 + inkscape:grid-bbox="true"
  274 + inkscape:window-width="1364"
  275 + inkscape:window-height="678"
  276 + inkscape:window-x="0"
  277 + inkscape:window-y="27"
  278 + objecttolerance="10"
  279 + gridtolerance="10"
  280 + guidetolerance="10"
  281 + inkscape:window-maximized="0">
  282 + <inkscape:grid
  283 + type="xygrid"
  284 + id="grid2382"
  285 + visible="true"
  286 + enabled="true"
  287 + originx="0.5px"
  288 + originy="0.5px"
  289 + empcolor="#0000ff"
  290 + empopacity="0.1254902"
  291 + dotted="true" />
  292 + </sodipodi:namedview>
  293 + <metadata
  294 + id="metadata2388">
  295 + <rdf:RDF>
  296 + <cc:Work
  297 + rdf:about="">
  298 + <dc:format>image/svg+xml</dc:format>
  299 + <dc:type
  300 + rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
  301 + </cc:Work>
  302 + </rdf:RDF>
  303 + </metadata>
  304 + <g
  305 + id="layer1"
  306 + inkscape:label="Layer 1"
  307 + inkscape:groupmode="layer">
  308 + <g
  309 + transform="translate(-247.62879,-298.93361)"
  310 + id="g5187">
  311 + <g
  312 + id="g4846">
  313 + <g
  314 + id="g3190-2"
  315 + style="opacity:0.4;filter:url(#filter3241-2)"
  316 + transform="translate(250.71429,299.93361)">
  317 + <rect
  318 + y="1.5"
  319 + x="1.5"
  320 + height="59"
  321 + width="11"
  322 + id="rect3184-1"
  323 + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
  324 + ry="2"
  325 + rx="2" />
  326 + </g>
  327 + <rect
  328 + y="300.43362"
  329 + x="251.21428"
  330 + height="59"
  331 + width="11"
  332 + id="rect2395-8"
  333 + style="fill:url(#linearGradient5832);fill-opacity:1;fill-rule:nonzero;stroke:#204a87;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
  334 + ry="2"
  335 + rx="2" />
  336 + <rect
  337 + ry="1"
  338 + style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
  339 + id="rect3158-7"
  340 + width="9"
  341 + height="57"
  342 + x="252.21428"
  343 + y="301.43362"
  344 + rx="1" />
  345 + </g>
  346 + <g
  347 + transform="matrix(0.69260722,0,0,1,81.51265,0)"
  348 + id="g5180">
  349 + <rect
  350 + rx="2"
  351 + ry="2"
  352 + style="opacity:0.4;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3241-4-8);enable-background:accumulate"
  353 + id="rect3188-8"
  354 + width="31"
  355 + height="59"
  356 + x="16.5"
  357 + y="2.5"
  358 + transform="matrix(1.4160224,0,0,0.76166071,243.80989,314.09132)" />
  359 + <rect
  360 + y="314.47638"
  361 + x="265.17426"
  362 + height="44.937984"
  363 + width="43.896694"
  364 + id="rect3156-3"
  365 + style="fill:url(#linearGradient5834);fill-opacity:1;fill-rule:nonzero;stroke:#204a87;stroke-width:1.03852236;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
  366 + ry="1.5233214" />
  367 + <rect
  368 + y="315.23804"
  369 + x="266.59027"
  370 + height="43.414661"
  371 + width="41.064651"
  372 + id="rect3162-1"
  373 + style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1.03852236;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
  374 + ry="0.7616607"
  375 + inkscape:export-xdpi="90"
  376 + inkscape:export-ydpi="90" />
  377 + </g>
  378 + <g
  379 + transform="matrix(0.9761091,0,0,1,6.3333026,0)"
  380 + id="g5108">
  381 + <rect
  382 + rx="2"
  383 + ry="2"
  384 + style="opacity:0.4;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3241-0);enable-background:accumulate"
  385 + id="rect3184-5"
  386 + width="11"
  387 + height="59"
  388 + x="2.5"
  389 + y="2.5"
  390 + transform="matrix(0,1.0025263,-0.76423683,0,312.09322,298.92289)" />
  391 + <g
  392 + transform="matrix(0,1,-1,0,611.46116,-45.820829)"
  393 + id="g4877-9">
  394 + <rect
  395 + ry="1.5284736"
  396 + style="fill:url(#linearGradient5836);fill-opacity:1;fill-rule:nonzero;stroke:#204a87;stroke-width:0.87531;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
  397 + id="rect2395-95"
  398 + width="11.02779"
  399 + height="45.089973"
  400 + x="346.19211"
  401 + y="301.27853" />
  402 + <rect
  403 + y="302.04276"
  404 + x="347.19461"
  405 + height="43.561501"
  406 + width="9.0227375"
  407 + id="rect3158-2"
  408 + style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:0.87531;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
  409 + ry="0.76423681" />
  410 + </g>
  411 + </g>
  412 + <g
  413 + id="g4877-8"
  414 + transform="translate(-47.956003,13.002947)">
  415 + <rect
  416 + y="301.27853"
  417 + x="346.19211"
  418 + height="45.089973"
  419 + width="11.02779"
  420 + id="rect2395-1"
  421 + style="fill:url(#linearGradient5838);fill-opacity:1;fill-rule:nonzero;stroke:#204a87;stroke-width:0.87531;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
  422 + ry="1.5284736" />
  423 + <rect
  424 + ry="0.76423681"
  425 + style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:0.87531;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
  426 + id="rect3158-71"
  427 + width="9.0227375"
  428 + height="43.561501"
  429 + x="347.19461"
  430 + y="302.04276" />
  431 + </g>
  432 + </g>
  433 + </g>
  434 +</svg>
... ...
public/designs/templates/topleft/stylesheets/style.css
... ... @@ -20,7 +20,7 @@
20 20  
21 21 .box-3 {
22 22 position: relative;
23   - display: table-footer-group;
  23 + display: table-header-group;
24 24 width: 100%;
25 25 }
26 26  
... ...
public/images/blocks/4.png 0 → 100644

1.14 KB

public/images/blocks/4.svg 0 → 100644
... ... @@ -0,0 +1,83 @@
  1 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2 +<!-- Created with Inkscape (http://www.inkscape.org/) -->
  3 +
  4 +<svg
  5 + xmlns:dc="http://purl.org/dc/elements/1.1/"
  6 + xmlns:cc="http://creativecommons.org/ns#"
  7 + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  8 + xmlns:svg="http://www.w3.org/2000/svg"
  9 + xmlns="http://www.w3.org/2000/svg"
  10 + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
  11 + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
  12 + width="64"
  13 + height="64"
  14 + id="svg2"
  15 + sodipodi:version="0.32"
  16 + inkscape:version="0.48.3.1 r9886"
  17 + version="1.0"
  18 + sodipodi:docname="4.svg"
  19 + inkscape:output_extension="org.inkscape.output.svg.inkscape"
  20 + inkscape:export-filename="/home/noosfero/sites/noosfero/public/images/blocks/4.png"
  21 + inkscape:export-xdpi="87.968124"
  22 + inkscape:export-ydpi="87.968124">
  23 + <defs
  24 + id="defs4" />
  25 + <sodipodi:namedview
  26 + id="base"
  27 + pagecolor="#ffffff"
  28 + bordercolor="#666666"
  29 + borderopacity="1.0"
  30 + inkscape:pageopacity="0.0"
  31 + inkscape:pageshadow="2"
  32 + inkscape:zoom="5.921875"
  33 + inkscape:cx="32"
  34 + inkscape:cy="32"
  35 + inkscape:document-units="px"
  36 + inkscape:current-layer="layer1"
  37 + width="64px"
  38 + height="64px"
  39 + inkscape:window-width="1366"
  40 + inkscape:window-height="681"
  41 + inkscape:window-x="0"
  42 + inkscape:window-y="27"
  43 + showgrid="false"
  44 + inkscape:window-maximized="1" />
  45 + <metadata
  46 + id="metadata7">
  47 + <rdf:RDF>
  48 + <cc:Work
  49 + rdf:about="">
  50 + <dc:format>image/svg+xml</dc:format>
  51 + <dc:type
  52 + rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
  53 + <dc:title></dc:title>
  54 + </cc:Work>
  55 + </rdf:RDF>
  56 + </metadata>
  57 + <g
  58 + inkscape:label="Camada 1"
  59 + inkscape:groupmode="layer"
  60 + id="layer1">
  61 + <path
  62 + sodipodi:type="arc"
  63 + style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:4.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.19607843"
  64 + id="path2162"
  65 + sodipodi:cx="24.12665"
  66 + sodipodi:cy="24.063324"
  67 + sodipodi:rx="21.593668"
  68 + sodipodi:ry="21.277044"
  69 + d="M 45.720318 24.063324 A 21.593668 21.277044 0 1 1 2.5329819,24.063324 A 21.593668 21.277044 0 1 1 45.720318 24.063324 z"
  70 + transform="translate(7.8733501,7.936676)" />
  71 + <text
  72 + xml:space="preserve"
  73 + style="font-size:42.00993729px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:0.19607843;stroke:none;font-family:FreeSans"
  74 + x="16.267668"
  75 + y="47.399117"
  76 + id="text3134"
  77 + sodipodi:linespacing="125%"><tspan
  78 + sodipodi:role="line"
  79 + id="tspan3136"
  80 + x="16.267668"
  81 + y="47.399117">4</tspan></text>
  82 + </g>
  83 +</svg>
... ...
public/images/control-panel/role-management.gif 0 → 100644

2.07 KB

public/images/control-panel/role-management.png 0 → 100644

3.63 KB

public/javascripts/application.js
... ... @@ -27,6 +27,7 @@
27 27 *= require manage-products.js
28 28 *= require catalog.js
29 29 *= require autogrow.js
  30 +*= require require_login.js
30 31 */
31 32  
32 33 // scope for noosfero stuff
... ...
public/javascripts/assign_role.js 0 → 100644
... ... @@ -0,0 +1,19 @@
  1 +(function($){
  2 + 'use strict';
  3 +
  4 + function toggle_assignment_method() {
  5 + if (this.value != "roles") {
  6 + $('.assign_by_roles').hide();
  7 + $('.assign_by_members').show();
  8 + } else {
  9 + $('.assign_by_members').hide();
  10 + $('.assign_by_roles').show();
  11 + }
  12 + }
  13 +
  14 + $(document).ready(function() {
  15 + $('.assign_by_roles').hide();
  16 + // Event triggers
  17 + $('.assign_role_by').click(toggle_assignment_method);
  18 + });
  19 +})(jQuery);
... ...
public/javascripts/require_login.js 0 → 100644
... ... @@ -0,0 +1,25 @@
  1 +(function($) {
  2 + $(window).bind('userDataLoaded', function(event, data) {
  3 + $(".require-login-popup").live('click', function(){
  4 + clicked = $(this);
  5 + url = clicked.attr("href");
  6 + if(url!=undefined && url!='' && url!='#') {
  7 + if(!data.login) {
  8 + url = $.param.querystring(url, "require_login_popup=true");
  9 + }
  10 + loading_for_button(this);
  11 + $.post(url, function(data){
  12 + if(data.require_login_popup) {
  13 + $('#link_login').click(); //TODO see a better way to show login popup
  14 + }
  15 + }).complete(function() {
  16 + clicked.css("cursor","");
  17 + $(".small-loading").remove();
  18 + });
  19 + } else {
  20 + $('#link_login').click();
  21 + }
  22 + return false;
  23 + });
  24 + });
  25 +})(jQuery);
... ...
public/stylesheets/application.css
... ... @@ -1842,6 +1842,9 @@ a.button.disabled, input.disabled {
1842 1842 #box-organizer div.box-3 {
1843 1843 background-image: url(../images/blocks/3.png);
1844 1844 }
  1845 +#box-organizer div.box-4 {
  1846 + background-image: url(../images/blocks/4.png);
  1847 +}
1845 1848 #box-organizer .block {
1846 1849 cursor: move;
1847 1850 }
... ... @@ -4685,6 +4688,12 @@ h1#agenda-title {
4685 4688 .controller-profile_editor a.control-panel-welcome-page {
4686 4689 background-image: url(../images/control-panel/welcome-page.png)
4687 4690 }
  4691 +.controller-profile_editor a.control-panel-roles {
  4692 + background-image: url(../images/control-panel/role-management.png)
  4693 +}
  4694 +.controller-profile_editor .msie6 a.control-panel-roles {
  4695 + background-image: url(../images/control-panel/role-management.gif)
  4696 +}
4688 4697 /* ==> public/stylesheets/controller_profile_members.css <== */
4689 4698 .controller-profile_members .no-boxes {
4690 4699 margin: 30px
... ...
script/install-dependencies/debian-wheezy.sh
1   -binary_packages='deb http://download.noosfero.org/debian/wheezy-1.1 ./'
  1 +binary_packages='deb http://download.noosfero.org/debian/wheezy-1.2 ./'
2 2  
3 3 source_packages=$(echo "$binary_packages" | sed -e 's/^deb/deb-src/')
4 4  
... ... @@ -53,6 +53,13 @@ FPQAoNmiMgP6zGF9rgOEWMEiFEryayrz
53 53 EOF
54 54 fi
55 55  
  56 +if grep -qrl wheezy /etc/apt/sources.list* && ! grep -qrl wheezy-backports /etc/apt/sources.list*; then
  57 + sudo tee /etc/apt/sources.list.d/backports.list <<EOF
  58 +deb http://httpredir.debian.org/debian wheezy-backports main
  59 +EOF
  60 +fi
  61 +
  62 +
56 63 if test -f tmp/debian/Release.gpg; then
57 64 echo "deb file://$(pwd)/tmp/debian/ ./" | sudo tee /etc/apt/sources.list.d/local.list
58 65 sudo apt-key add tmp/debian/signing-key.asc
... ... @@ -65,6 +72,9 @@ run sudo apt-get -qy dist-upgrade
65 72  
66 73 run sudo apt-get -y install dctrl-tools
67 74  
  75 +# *sigh* need ruby-rspec from backports
  76 +run sudo apt-get -y install -t wheezy-backports ruby-rspec
  77 +
68 78 # needed to run noosfero
69 79 packages=$(grep-dctrl -n -s Build-Depends,Depends,Recommends -S -X noosfero debian/control | sed -e '/^\s*#/d; s/([^)]*)//g; s/,\s*/\n/g' | grep -v 'memcached\|debconf\|dbconfig-common\|misc:Depends\|adduser\|mail-transport-agent')
70 80 run sudo apt-get -y install $packages
... ...
test/functional/content_viewer_controller_test.rb
... ... @@ -175,7 +175,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
175 175 admin = fast_create(Person)
176 176 community.add_member(admin)
177 177  
178   - folder = fast_create(Folder, :profile_id => community.id, :published => false)
  178 + folder = fast_create(Folder, :profile_id => community.id, :published => false, :show_to_followers => false)
179 179 community.add_member(profile)
180 180 login_as(profile.identifier)
181 181  
... ... @@ -278,7 +278,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
278 278 should 'not give access to private articles if logged in and only member' do
279 279 person = create_user('test_user').person
280 280 profile = Profile.create!(:name => 'test profile', :identifier => 'test_profile')
281   - intranet = Folder.create!(:name => 'my_intranet', :profile => profile, :published => false)
  281 + intranet = Folder.create!(:name => 'my_intranet', :profile => profile, :published => false, :show_to_followers => false)
282 282 profile.affiliate(person, Profile::Roles.member(profile.environment.id))
283 283 login_as('test_user')
284 284  
... ...
test/functional/profile_roles_controller_test.rb 0 → 100644
... ... @@ -0,0 +1,106 @@
  1 +require_relative "../test_helper"
  2 +require 'profile_roles_controller'
  3 +
  4 +class ProfileRolesControllerTest < ActionController::TestCase
  5 +
  6 + def setup
  7 + @controller = ProfileRolesController.new
  8 + @request = ActionController::TestRequest.new
  9 + @response = ActionController::TestResponse.new
  10 + @role = Role.find(:first)
  11 + end
  12 +
  13 + should 'create a custom role' do
  14 + community = fast_create(Community)
  15 + admin = create_user_with_permission('admin_user', 'manage_custom_roles', community)
  16 + login_as :admin_user
  17 + post :create, :profile => community.identifier, :role => {:name => "some_role", :permissions => ["edit_profile"] }
  18 + role = Role.where(:name => 'some_role').first
  19 +
  20 + assert_not_nil role
  21 + assert_equal community.id, role.profile_id
  22 + end
  23 +
  24 + should 'not create a custom role without permission' do
  25 + community = fast_create(Community)
  26 + moderator = create_user_with_permission('profile_admin', 'edit_profile', community)
  27 + login_as :profile_admin
  28 + post :create, :profile => community.identifier, :role => {:name => "new_admin", :permissions => ["edit_profile"] }
  29 +
  30 + assert_response 403
  31 + assert_template 'access_denied'
  32 +
  33 + role = Role.where(:name => 'new_admin')
  34 +
  35 + assert_empty role
  36 + end
  37 +
  38 +
  39 + should 'delete a custom role not used' do
  40 + community = fast_create(Community)
  41 + admin = create_user_with_permission('admin_user', 'manage_custom_roles', community)
  42 + login_as :admin_user
  43 + role = Role.create!({:name => 'delete_article', :key => 'profile_delete_article', :profile_id => community.id, :environment => Environment.default}, :without_protection => true)
  44 + post :remove , :profile => community.identifier, :id => role.id
  45 +
  46 + assert_response :redirect
  47 + assert_redirected_to :action => 'index'
  48 +
  49 + assert_not_includes Role.all, role
  50 + end
  51 +
  52 + should 'delete a custom role being used' do
  53 + community = fast_create(Community)
  54 + admin = create_user_with_permission('admin_user', 'manage_custom_roles', community)
  55 + login_as :admin_user
  56 + role = Role.create!({:name => 'delete_article', :key => 'profile_delete_article', :profile_id => community.id, :environment => Environment.default}, :without_protection => true)
  57 + admin.add_role(role, community)
  58 + moderator_role = Role.find_by_name("moderator")
  59 +
  60 + assert_not_includes community.members_by_role(moderator_role), admin
  61 +
  62 + post :remove , :profile => community.identifier, :id => role.id, :roles => [moderator_role.id]
  63 +
  64 + assert_response :redirect
  65 + assert_redirected_to :action => 'index'
  66 +
  67 + assert_not_includes Role.all, role
  68 + assert_includes community.members_by_role(moderator_role), admin
  69 + end
  70 +
  71 + should 'assign a custom role to single user' do
  72 + community = fast_create(Community)
  73 + admin = create_user_with_permission('admin_user', 'manage_custom_roles', community)
  74 + login_as :admin_user
  75 + role = Role.create!({:name => 'delete_article', :key => 'profile_delete_article', :profile_id => community.id, :environment => Environment.default}, :without_protection => true)
  76 +
  77 + assert_not_includes community.members_by_role(role), admin
  78 +
  79 + post :define, :profile => community.identifier, :id => role.id, :assign_role_by => "members", :person_id => admin.id
  80 +
  81 + assert_includes community.members_by_role(role), admin
  82 + end
  83 +
  84 + should 'replace a role with a custom role' do
  85 + community = fast_create(Community)
  86 + admin = create_user_with_permission('admin_user', 'manage_custom_roles', community)
  87 + moderator = create_user_with_permission('profile_admin', 'edit_profile', community)
  88 + login_as :admin_user
  89 + role = Role.create!({:name => 'delete_article', :key => 'profile_delete_article', :profile_id => community.id, :environment => Environment.default}, :without_protection => true)
  90 + moderator_role = Role.find_by_name("moderator")
  91 + admin.add_role(moderator_role, community)
  92 +
  93 + assert_not_includes community.members_by_role(role), admin
  94 +
  95 + assert_not_includes community.members_by_role(role), moderator
  96 + assert_not_includes community.members_by_role(moderator_role), moderator
  97 +
  98 + post :define, :profile => community.identifier, :id => role.id, :assign_role_by => "roles", :selected_role => moderator_role.id
  99 +
  100 + assert_not_includes community.members_by_role(moderator_role), admin
  101 + assert_includes community.members_by_role(role), admin
  102 +
  103 + assert_not_includes community.members_by_role(role), moderator
  104 + assert_not_includes community.members_by_role(moderator_role), moderator
  105 + end
  106 +end
... ...
test/unit/enterprise_test.rb
... ... @@ -188,7 +188,7 @@ class EnterpriseTest &lt; ActiveSupport::TestCase
188 188 inactive_template.save!
189 189  
190 190 active_template = create(Enterprise, :name => 'enteprise template', :identifier => 'enterprise_template')
191   - assert_equal 3, active_template.boxes.size
  191 + assert_equal 4, active_template.boxes.size
192 192  
193 193 e = Environment.default
194 194 e.inactive_enterprise_template = inactive_template
... ... @@ -400,7 +400,7 @@ class EnterpriseTest &lt; ActiveSupport::TestCase
400 400 e.save!
401 401  
402 402 ent = create(Enterprise, :name => 'test enteprise', :identifier => 'test_ent')
403   - assert_equal 3, ent.boxes.size
  403 + assert_equal 4, ent.boxes.size
404 404 end
405 405  
406 406 should 'collect the highlighted products with image' do
... ...
test/unit/profile_test.rb
... ... @@ -901,6 +901,8 @@ class ProfileTest &lt; ActiveSupport::TestCase
901 901  
902 902 should 'copy set of articles from a template' do
903 903 template = create_user('test_template').person
  904 + template.is_template = true
  905 + template.save
904 906 template.articles.destroy_all
905 907 a1 = fast_create(Article, :profile_id => template.id, :name => 'some xyz article')
906 908 a2 = fast_create(Article, :profile_id => template.id, :name => 'some child article', :parent_id => a1.id)
... ... @@ -934,6 +936,8 @@ class ProfileTest &lt; ActiveSupport::TestCase
934 936  
935 937 should 'copy homepage from template' do
936 938 template = create_user('test_template').person
  939 + template.is_template = true
  940 + template.save
937 941 template.articles.destroy_all
938 942 a1 = fast_create(Article, :profile_id => template.id, :name => 'some xyz article')
939 943 template.home_page = a1
... ... @@ -949,6 +953,8 @@ class ProfileTest &lt; ActiveSupport::TestCase
949 953  
950 954 should 'not advertise the articles copied from templates' do
951 955 template = create_user('test_template').person
  956 + template.is_template = true
  957 + template.save
952 958 template.articles.destroy_all
953 959 a = fast_create(Article, :profile_id => template.id, :name => 'some xyz article')
954 960  
... ... @@ -962,7 +968,7 @@ class ProfileTest &lt; ActiveSupport::TestCase
962 968 end
963 969  
964 970 should 'copy set of boxes from profile template' do
965   - template = fast_create(Profile)
  971 + template = fast_create(Profile, :is_template => true)
966 972 template.boxes.destroy_all
967 973 template.boxes << Box.new
968 974 template.boxes[0].blocks << Block.new
... ... @@ -977,7 +983,7 @@ class ProfileTest &lt; ActiveSupport::TestCase
977 983 end
978 984  
979 985 should 'copy layout template when applying template' do
980   - template = fast_create(Profile)
  986 + template = fast_create(Profile, :is_template => true)
981 987 template.layout_template = 'leftbar'
982 988 template.save!
983 989  
... ... @@ -989,7 +995,7 @@ class ProfileTest &lt; ActiveSupport::TestCase
989 995 end
990 996  
991 997 should 'copy blocks when applying template' do
992   - template = fast_create(Profile)
  998 + template = fast_create(Profile, :is_template => true)
993 999 template.boxes.destroy_all
994 1000 template.boxes << Box.new
995 1001 template.boxes[0].blocks << Block.new
... ... @@ -1004,7 +1010,7 @@ class ProfileTest &lt; ActiveSupport::TestCase
1004 1010 end
1005 1011  
1006 1012 should 'copy articles when applying template' do
1007   - template = fast_create(Profile)
  1013 + template = fast_create(Profile, :is_template => true)
1008 1014 template.articles.create(:name => 'template article')
1009 1015 template.save!
1010 1016  
... ... @@ -1016,7 +1022,7 @@ class ProfileTest &lt; ActiveSupport::TestCase
1016 1022 end
1017 1023  
1018 1024 should 'rename existing articles when applying template' do
1019   - template = fast_create(Profile)
  1025 + template = fast_create(Profile, :is_template => true)
1020 1026 template.boxes.destroy_all
1021 1027 template.boxes << Box.new
1022 1028 template.boxes[0].blocks << Block.new
... ... @@ -1033,7 +1039,7 @@ class ProfileTest &lt; ActiveSupport::TestCase
1033 1039 end
1034 1040  
1035 1041 should 'copy header when applying template' do
1036   - template = fast_create(Profile)
  1042 + template = fast_create(Profile, :is_template => true)
1037 1043 template[:custom_header] = '{name}'
1038 1044 template.save!
1039 1045  
... ... @@ -1047,7 +1053,7 @@ class ProfileTest &lt; ActiveSupport::TestCase
1047 1053 end
1048 1054  
1049 1055 should 'copy footer when applying template' do
1050   - template = create(Profile, :address => 'Template address', :custom_footer => '{address}')
  1056 + template = create(Profile, :address => 'Template address', :custom_footer => '{address}', :is_template => true)
1051 1057  
1052 1058 p = create(Profile, :address => 'Profile address')
1053 1059 p.apply_template(template)
... ... @@ -1058,7 +1064,7 @@ class ProfileTest &lt; ActiveSupport::TestCase
1058 1064 end
1059 1065  
1060 1066 should 'ignore failing validation when applying template' do
1061   - template = create(Profile, :layout_template => 'leftbar', :custom_footer => 'my custom footer', :custom_header => 'my custom header')
  1067 + template = create(Profile, :layout_template => 'leftbar', :custom_footer => 'my custom footer', :custom_header => 'my custom header', :is_template => true)
1062 1068  
1063 1069 p = create(Profile)
1064 1070 def p.validate
... ... @@ -1074,7 +1080,7 @@ class ProfileTest &lt; ActiveSupport::TestCase
1074 1080 end
1075 1081  
1076 1082 should 'copy homepage when applying template' do
1077   - template = fast_create(Profile)
  1083 + template = fast_create(Profile, :is_template => true)
1078 1084 a1 = fast_create(Article, :profile_id => template.id, :name => 'some xyz article')
1079 1085 template.home_page = a1
1080 1086 template.save!
... ... @@ -1161,7 +1167,7 @@ class ProfileTest &lt; ActiveSupport::TestCase
1161 1167 end
1162 1168  
1163 1169 should 'copy public/private setting from template' do
1164   - template = fast_create(Profile, :public_profile => false)
  1170 + template = fast_create(Profile, :public_profile => false, :is_template => true)
1165 1171 p = fast_create(Profile)
1166 1172 p.apply_template(template)
1167 1173 assert_equal false, p.public_profile
... ...
util/debian-install/Vagrantfile
... ... @@ -13,9 +13,11 @@ else
13 13 local_debs = Dir.glob('*.deb')
14 14 debs.each do |f|
15 15 fn = File.basename(f)
16   - if local_debs.include?(fn)
17   - local_debs.delete(fn)
18   - else
  16 +
  17 + local_debs.delete(fn)
  18 +
  19 + if File.stat(f) != File.stat(fn)
  20 + FileUtils::Verbose.rm_f(fn)
19 21 FileUtils::Verbose.ln f, '.'
20 22 end
21 23 end
... ...
util/debian-install/install
... ... @@ -61,19 +61,35 @@ deb http://download.noosfero.org/debian/wheezy-test ./
61 61 deb-src http://download.noosfero.org/debian/wheezy-test ./
62 62 EOF
63 63  
  64 +sed -e 's/wheezy/&-backports/' \
  65 + /etc/apt/sources.list > /etc/apt/sources.list.d/backports.list
  66 +
64 67 export DEBIAN_FRONTEND=noninteractive
65 68  
  69 +# local debs
  70 +if [ -n "$(find /vagrant -name '*.deb')" ]; then
  71 + apt-get install -qy apt-utils bzip2
  72 + (
  73 + rm -rf /opt/noosfero
  74 + mkdir /opt/noosfero
  75 + cp /vagrant/*.deb /opt/noosfero
  76 + cd /opt/noosfero
  77 + apt-ftparchive packages . > Packages
  78 + cat Packages | gzip - > Packages.gz
  79 + cat Packages | bzip2 - > Packages.bz2
  80 + apt-ftparchive release . > Release
  81 + echo 'deb [trusted=yes] file:///opt/noosfero ./' > /etc/apt/sources.list.d/local.list
  82 + )
  83 +else
  84 + rm -f /etc/apt/sources.list.d/local.list
  85 +fi
  86 +
66 87 apt-get update
67 88 apt-get dist-upgrade -qy
68   -apt-get install -qy postgresql ruby1.8
  89 +apt-get install -qy postgresql
69 90  
70   -if dpkg --unpack /vagrant/noosfero_*.deb /vagrant/noosfero-apache_*.deb; then
71   - apt-cache policy noosfero
72   - apt-get install -qyf
73   -else
74   - apt-cache policy noosfero
75   - apt-get install -qy noosfero noosfero-apache
76   -fi
  91 +apt-cache policy noosfero
  92 +apt-get install -qy noosfero noosfero-apache
77 93  
78 94 a2dissite 000-default
79 95 service apache2 reload
... ...
vendor/plugins/access_control/lib/role.rb
... ... @@ -4,6 +4,7 @@ class Role &lt; ActiveRecord::Base
4 4  
5 5 has_many :role_assignments, :dependent => :destroy
6 6 belongs_to :environment
  7 + belongs_to :organization
7 8 serialize :permissions, Array
8 9 validates_presence_of :name
9 10 validates_uniqueness_of :name, :scope => :environment_id
... ...