Commit c07e14448e7fb9a807789cc2266c4327adfe762a

Authored by Leandro Santos
2 parents 7bb5bd94 12d04695

Merge branch 'master' into api

@@ -92,6 +92,7 @@ Daniel Alves + Rafael Manzo <rr.manzo@gmail.com> @@ -92,6 +92,7 @@ Daniel Alves + Rafael Manzo <rr.manzo@gmail.com>
92 Daniela Soares Feitosa <danielafeitosa@colivre.coop.br> 92 Daniela Soares Feitosa <danielafeitosa@colivre.coop.br>
93 Daniel Bucher <daniel.bucher88@gmail.com> 93 Daniel Bucher <daniel.bucher88@gmail.com>
94 Daniel Cunha <daniel@colivre.coop.br> 94 Daniel Cunha <daniel@colivre.coop.br>
  95 +daniel <dtygel@eita.org.br>
95 David Carlos <ddavidcarlos1392@gmail.com> 96 David Carlos <ddavidcarlos1392@gmail.com>
96 diegoamc <diegoamc90@gmail.com> 97 diegoamc <diegoamc90@gmail.com>
97 Diego Araújo + Alessandro Palmeira <diegoamc90@gmail.com> 98 Diego Araújo + Alessandro Palmeira <diegoamc90@gmail.com>
@@ -120,6 +121,7 @@ Diego Araujo + Rodrigo Souto + Rafael Manzo &lt;rr.manzo@gmail.com&gt; @@ -120,6 +121,7 @@ Diego Araujo + Rodrigo Souto + Rafael Manzo &lt;rr.manzo@gmail.com&gt;
120 Diego + Jefferson <diegoamc90@gmail.com> 121 Diego + Jefferson <diegoamc90@gmail.com>
121 Diego Martinez <diegoamc90@gmail.com> 122 Diego Martinez <diegoamc90@gmail.com>
122 Diego + Renan <renanteruoc@gmail.com> 123 Diego + Renan <renanteruoc@gmail.com>
  124 +dtygel <dtygel@gmail.com>
123 DylanGuedes <djmgguedes@gmail.com> 125 DylanGuedes <djmgguedes@gmail.com>
124 Eduardo Passos <eduardo@risa.localdomain.localhost> 126 Eduardo Passos <eduardo@risa.localdomain.localhost>
125 Eduardo Passos <eduardosteps@gmail.com> 127 Eduardo Passos <eduardosteps@gmail.com>
@@ -144,6 +146,7 @@ Italo Valcy &lt;italo@dcc.ufba.br&gt; @@ -144,6 +146,7 @@ Italo Valcy &lt;italo@dcc.ufba.br&gt;
144 Jefferson Fernandes + Diego Araujo + Rafael Manzo <jeffs.fernandes@gmail.com> 146 Jefferson Fernandes + Diego Araujo + Rafael Manzo <jeffs.fernandes@gmail.com>
145 Jefferson Fernandes + Joao M. M. da Silva <jeffs.fernandes@gmail.com> 147 Jefferson Fernandes + Joao M. M. da Silva <jeffs.fernandes@gmail.com>
146 Jefferson Fernandes + Joao M. M. Silva <jeffs.fernandes@gmail.com> 148 Jefferson Fernandes + Joao M. M. Silva <jeffs.fernandes@gmail.com>
  149 +Jérôme Jutteau <j.jutteau@gmail.com>
147 João da Silva + Eduardo Morais + Rafael Manzo <rr.manzo@gmail.com> 150 João da Silva + Eduardo Morais + Rafael Manzo <rr.manzo@gmail.com>
148 João da Silva <jaodsilv@linux.ime.usp.br> 151 João da Silva <jaodsilv@linux.ime.usp.br>
149 João Marco Maciel da Silva + Rafael Manzo + Renan Teruo <jaodsilv@linux.ime.usp.br> 152 João Marco Maciel da Silva + Rafael Manzo + Renan Teruo <jaodsilv@linux.ime.usp.br>
@@ -247,8 +250,10 @@ Tallys Martins &lt;tallysmartins@gmail.com&gt; @@ -247,8 +250,10 @@ Tallys Martins &lt;tallysmartins@gmail.com&gt;
247 Tallys Martins <tallysmartins@yahoo.com.br> 250 Tallys Martins <tallysmartins@yahoo.com.br>
248 tallys <tallys@tallys> 251 tallys <tallys@tallys>
249 tallys <tallys@tallys.(none)> 252 tallys <tallys@tallys.(none)>
  253 +Thiago Casotti <thiago.casotti@uol.com.br>
250 Thiago Zoroastro <thiago.zoroastro@bol.com.br> 254 Thiago Zoroastro <thiago.zoroastro@bol.com.br>
251 Tuux <tuxa@galaxie.eu.org> 255 Tuux <tuxa@galaxie.eu.org>
  256 +TWS <tablettws@gmail.com>
252 Valessio Brito <contato@valessiobrito.com.br> 257 Valessio Brito <contato@valessiobrito.com.br>
253 Valessio Brito <contato@valessiobrito.info> 258 Valessio Brito <contato@valessiobrito.info>
254 Valessio Brito <valessio@gmail.com> 259 Valessio Brito <valessio@gmail.com>
app/controllers/application_controller.rb
@@ -9,6 +9,7 @@ class ApplicationController &lt; ActionController::Base @@ -9,6 +9,7 @@ class ApplicationController &lt; ActionController::Base
9 before_filter :allow_cross_domain_access 9 before_filter :allow_cross_domain_access
10 before_filter :login_required, :if => :private_environment? 10 before_filter :login_required, :if => :private_environment?
11 before_filter :verify_members_whitelist, :if => [:private_environment?, :user] 11 before_filter :verify_members_whitelist, :if => [:private_environment?, :user]
  12 + before_filter :redirect_to_current_user
12 13
13 def verify_members_whitelist 14 def verify_members_whitelist
14 render_access_denied unless user.is_admin? || environment.in_whitelist?(user) 15 render_access_denied unless user.is_admin? || environment.in_whitelist?(user)
@@ -192,4 +193,15 @@ class ApplicationController &lt; ActionController::Base @@ -192,4 +193,15 @@ class ApplicationController &lt; ActionController::Base
192 def private_environment? 193 def private_environment?
193 @environment.enabled?(:restrict_to_members) 194 @environment.enabled?(:restrict_to_members)
194 end 195 end
  196 +
  197 + def redirect_to_current_user
  198 + if params[:profile] == '~'
  199 + if logged_in?
  200 + redirect_to params.merge(:profile => user.identifier)
  201 + else
  202 + render_not_found
  203 + end
  204 + end
  205 + end
  206 +
195 end 207 end
app/controllers/my_profile/profile_design_controller.rb
@@ -4,11 +4,19 @@ class ProfileDesignController &lt; BoxOrganizerController @@ -4,11 +4,19 @@ class ProfileDesignController &lt; BoxOrganizerController
4 4
5 protect 'edit_profile_design', :profile 5 protect 'edit_profile_design', :profile
6 6
7 - before_filter :protect_fixed_block, :only => [:save, :move_block] 7 + before_filter :protect_uneditable_block, :only => [:save]
  8 + before_filter :protect_fixed_block, :only => [:move_block]
  9 +
  10 + def protect_uneditable_block
  11 + block = boxes_holder.blocks.find(params[:id].gsub(/^block-/, ''))
  12 + if !current_person.is_admin? && !block.editable?
  13 + render_access_denied
  14 + end
  15 + end
8 16
9 def protect_fixed_block 17 def protect_fixed_block
10 block = boxes_holder.blocks.find(params[:id].gsub(/^block-/, '')) 18 block = boxes_holder.blocks.find(params[:id].gsub(/^block-/, ''))
11 - if block.fixed && !current_person.is_admin? 19 + if !current_person.is_admin? && !block.movable?
12 render_access_denied 20 render_access_denied
13 end 21 end
14 end 22 end
app/helpers/boxes_helper.rb
@@ -190,7 +190,7 @@ module BoxesHelper @@ -190,7 +190,7 @@ module BoxesHelper
190 else 190 else
191 "before-block-#{block.id}" 191 "before-block-#{block.id}"
192 end 192 end
193 - if block.nil? or modifiable?(block) 193 + if block.nil? || movable?(block)
194 content_tag('div', '&nbsp;', :id => id, :class => 'block-target' ) + drop_receiving_element(id, :url => { :action => 'move_block', :target => id }, :accept => box.acceptable_blocks, :hoverclass => 'block-target-hover') 194 content_tag('div', '&nbsp;', :id => id, :class => 'block-target' ) + drop_receiving_element(id, :url => { :action => 'move_block', :target => id }, :accept => box.acceptable_blocks, :hoverclass => 'block-target-hover')
195 else 195 else
196 "" 196 ""
@@ -199,14 +199,14 @@ module BoxesHelper @@ -199,14 +199,14 @@ module BoxesHelper
199 199
200 # makes the given block draggable so it can be moved away. 200 # makes the given block draggable so it can be moved away.
201 def block_handle(block) 201 def block_handle(block)
202 - modifiable?(block) ? draggable_element("block-#{block.id}", :revert => true) : "" 202 + movable?(block) ? draggable_element("block-#{block.id}", :revert => true) : ""
203 end 203 end
204 204
205 def block_edit_buttons(block) 205 def block_edit_buttons(block)
206 buttons = [] 206 buttons = []
207 nowhere = 'javascript: return false;' 207 nowhere = 'javascript: return false;'
208 208
209 - if modifiable?(block) 209 + if movable?(block)
210 if block.first? 210 if block.first?
211 buttons << icon_button('up-disabled', _("Can't move up anymore."), nowhere) 211 buttons << icon_button('up-disabled', _("Can't move up anymore."), nowhere)
212 else 212 else
@@ -229,15 +229,15 @@ module BoxesHelper @@ -229,15 +229,15 @@ module BoxesHelper
229 buttons << icon_button('left', _('Move to the opposite side'), { :action => 'move_block', :target => 'end-of-box-' + holder.boxes[1].id.to_s, :id => block.id }, :method => 'post' ) 229 buttons << icon_button('left', _('Move to the opposite side'), { :action => 'move_block', :target => 'end-of-box-' + holder.boxes[1].id.to_s, :id => block.id }, :method => 'post' )
230 end 230 end
231 end 231 end
  232 + end
232 233
233 - if block.editable?  
234 - buttons << modal_icon_button(:edit, _('Edit'), { :action => 'edit', :id => block.id })  
235 - end 234 + if editable?(block)
  235 + buttons << modal_icon_button(:edit, _('Edit'), { :action => 'edit', :id => block.id })
  236 + end
236 237
237 - if !block.main?  
238 - buttons << icon_button(:delete, _('Remove block'), { :action => 'remove', :id => block.id }, { :method => 'post', :confirm => _('Are you sure you want to remove this block?')})  
239 - buttons << icon_button(:clone, _('Clone'), { :action => 'clone_block', :id => block.id }, { :method => 'post' })  
240 - end 238 + if movable?(block) && !block.main?
  239 + buttons << icon_button(:delete, _('Remove block'), { :action => 'remove', :id => block.id }, { :method => 'post', :confirm => _('Are you sure you want to remove this block?')})
  240 + buttons << icon_button(:clone, _('Clone'), { :action => 'clone_block', :id => block.id }, { :method => 'post' })
241 end 241 end
242 242
243 if block.respond_to?(:help) 243 if block.respond_to?(:help)
@@ -273,7 +273,11 @@ module BoxesHelper @@ -273,7 +273,11 @@ module BoxesHelper
273 classes 273 classes
274 end 274 end
275 275
276 - def modifiable?(block)  
277 - return !block.fixed || environment.admins.include?(user) 276 + def movable?(block)
  277 + return block.movable? || user.is_admin?
  278 + end
  279 +
  280 + def editable?(block)
  281 + return block.editable? || user.is_admin?
278 end 282 end
279 end 283 end
app/models/block.rb
1 class Block < ActiveRecord::Base 1 class Block < ActiveRecord::Base
2 2
3 - attr_accessible :title, :display, :limit, :box_id, :posts_per_page, :visualization_format, :language, :display_user, :box, :fixed 3 + attr_accessible :title, :display, :limit, :box_id, :posts_per_page,
  4 + :visualization_format, :language, :display_user,
  5 + :box, :edit_modes, :move_modes
4 6
5 # to be able to generate HTML 7 # to be able to generate HTML
6 include ActionView::Helpers::UrlHelper 8 include ActionView::Helpers::UrlHelper
@@ -110,8 +112,13 @@ class Block &lt; ActiveRecord::Base @@ -110,8 +112,13 @@ class Block &lt; ActiveRecord::Base
110 # * <tt>'all'</tt>: the block is always displayed 112 # * <tt>'all'</tt>: the block is always displayed
111 settings_items :language, :type => :string, :default => 'all' 113 settings_items :language, :type => :string, :default => 'all'
112 114
113 - # The block can be configured to be fixed. Only can be edited by environment admins  
114 - settings_items :fixed, :type => :boolean, :default => false 115 + # The block can be configured to define the edition modes options. Only can be edited by environment admins
  116 + # It can assume the following values:
  117 + #
  118 + # * <tt>'all'</tt>: the block owner has all edit options for this block
  119 + # * <tt>'none'</tt>: the block owner can't do anything with the block
  120 + settings_items :edit_modes, :type => :string, :default => 'all'
  121 + settings_items :move_modes, :type => :string, :default => 'all'
115 122
116 # returns the description of the block, used when the user sees a list of 123 # returns the description of the block, used when the user sees a list of
117 # blocks to choose one to include in the design. 124 # blocks to choose one to include in the design.
@@ -148,7 +155,11 @@ class Block &lt; ActiveRecord::Base @@ -148,7 +155,11 @@ class Block &lt; ActiveRecord::Base
148 155
149 # Is this block editable? (Default to <tt>false</tt>) 156 # Is this block editable? (Default to <tt>false</tt>)
150 def editable? 157 def editable?
151 - true 158 + self.edit_modes == "all"
  159 + end
  160 +
  161 + def movable?
  162 + self.move_modes == "all"
152 end 163 end
153 164
154 # must always return false, except on MainBlock clas. 165 # must always return false, except on MainBlock clas.
@@ -228,6 +239,21 @@ class Block &lt; ActiveRecord::Base @@ -228,6 +239,21 @@ class Block &lt; ActiveRecord::Base
228 } 239 }
229 end 240 end
230 241
  242 + def edit_block_options
  243 + @edit_options ||= {
  244 + 'all' => _('Can be modified'),
  245 + 'none' => _('Cannot be modified')
  246 + }
  247 + end
  248 +
  249 + def move_block_options
  250 + @move_options ||= {
  251 + 'all' => _('Can be moved'),
  252 + 'none' => _('Cannot be moved')
  253 + }
  254 + end
  255 +
  256 +
231 def duplicate 257 def duplicate
232 duplicated_block = self.dup 258 duplicated_block = self.dup
233 duplicated_block.display = 'never' 259 duplicated_block.display = 'never'
app/views/box_organizer/edit.html.erb
@@ -5,12 +5,6 @@ @@ -5,12 +5,6 @@
5 5
6 <%= labelled_form_field(_('Custom title for this block: '), text_field(:block, :title, :maxlength => 20)) %> 6 <%= labelled_form_field(_('Custom title for this block: '), text_field(:block, :title, :maxlength => 20)) %>
7 7
8 - <% if environment.admins.include?(user) %>  
9 - <div class="fixed_block">  
10 - <%= labelled_check_box(_("Fixed"), "block[fixed]", value = "1", checked = @block.fixed) %>  
11 - </div>  
12 - <% end %>  
13 -  
14 <%= render :partial => partial_for_class(@block.class) %> 8 <%= render :partial => partial_for_class(@block.class) %>
15 9
16 <div class="display"> 10 <div class="display">
@@ -25,6 +19,15 @@ @@ -25,6 +19,15 @@
25 19
26 <%= labelled_form_field(_('Show for:'), select(:block, :language, [ [ _('all languages'), 'all']] + environment.locales.map {|key, value| [value, key]} )) %> 20 <%= labelled_form_field(_('Show for:'), select(:block, :language, [ [ _('all languages'), 'all']] + environment.locales.map {|key, value| [value, key]} )) %>
27 21
  22 + <% if user.is_admin? %>
  23 + <div class="edit-modes">
  24 + <%= labelled_form_field _('Edit options:'), select_tag('block[edit_modes]', options_from_collection_for_select(@block.edit_block_options, :first, :last, @block.edit_modes)) %>
  25 + </div>
  26 + <div class="move-modes">
  27 + <%= labelled_form_field _('Move options:'), select_tag('block[move_modes]', options_from_collection_for_select(@block.move_block_options, :first, :last, @block.move_modes)) %>
  28 + </div>
  29 + <% end %>
  30 +
28 <% button_bar do %> 31 <% button_bar do %>
29 <%= submit_button(:save, _('Save')) %> 32 <%= submit_button(:save, _('Save')) %>
30 <%= modal_close_button(_('Cancel')) %> 33 <%= modal_close_button(_('Cancel')) %>
config/routes.rb
@@ -56,37 +56,37 @@ Noosfero::Application.routes.draw do @@ -56,37 +56,37 @@ Noosfero::Application.routes.draw do
56 match 'search(/:action(/*category_path))', :controller => 'search' 56 match 'search(/:action(/*category_path))', :controller => 'search'
57 57
58 # events 58 # events
59 - match 'profile/:profile/events_by_day', :controller => 'events', :action => 'events_by_day', :profile => /#{Noosfero.identifier_format}/  
60 - match 'profile/:profile/events_by_month', :controller => 'events', :action => 'events_by_month', :profile => /#{Noosfero.identifier_format}/  
61 - match 'profile/:profile/events/:year/:month/:day', :controller => 'events', :action => 'events', :year => /\d*/, :month => /\d*/, :day => /\d*/, :profile => /#{Noosfero.identifier_format}/  
62 - match 'profile/:profile/events/:year/:month', :controller => 'events', :action => 'events', :year => /\d*/, :month => /\d*/, :profile => /#{Noosfero.identifier_format}/  
63 - match 'profile/:profile/events', :controller => 'events', :action => 'events', :profile => /#{Noosfero.identifier_format}/ 59 + match 'profile/:profile/events_by_day', :controller => 'events', :action => 'events_by_day', :profile => /#{Noosfero.identifier_format_in_url}/
  60 + match 'profile/:profile/events_by_month', :controller => 'events', :action => 'events_by_month', :profile => /#{Noosfero.identifier_format_in_url}/
  61 + match 'profile/:profile/events/:year/:month/:day', :controller => 'events', :action => 'events', :year => /\d*/, :month => /\d*/, :day => /\d*/, :profile => /#{Noosfero.identifier_format_in_url}/
  62 + match 'profile/:profile/events/:year/:month', :controller => 'events', :action => 'events', :year => /\d*/, :month => /\d*/, :profile => /#{Noosfero.identifier_format_in_url}/
  63 + match 'profile/:profile/events', :controller => 'events', :action => 'events', :profile => /#{Noosfero.identifier_format_in_url}/
64 64
65 # catalog 65 # catalog
66 - match 'catalog/:profile', :controller => 'catalog', :action => 'index', :profile => /#{Noosfero.identifier_format}/, :as => :catalog 66 + match 'catalog/:profile', :controller => 'catalog', :action => 'index', :profile => /#{Noosfero.identifier_format_in_url}/, :as => :catalog
67 67
68 # invite 68 # invite
69 - match 'profile/:profile/invite/friends', :controller => 'invite', :action => 'invite_friends', :profile => /#{Noosfero.identifier_format}/  
70 - match 'profile/:profile/invite/:action', :controller => 'invite', :profile => /#{Noosfero.identifier_format}/ 69 + match 'profile/:profile/invite/friends', :controller => 'invite', :action => 'invite_friends', :profile => /#{Noosfero.identifier_format_in_url}/
  70 + match 'profile/:profile/invite/:action', :controller => 'invite', :profile => /#{Noosfero.identifier_format_in_url}/
71 71
72 # feeds per tag 72 # feeds per tag
73 - match 'profile/:profile/tags/:id/feed', :controller => 'profile', :action =>'tag_feed', :id => /.+/, :profile => /#{Noosfero.identifier_format}/, :as => :tag_feed 73 + match 'profile/:profile/tags/:id/feed', :controller => 'profile', :action =>'tag_feed', :id => /.+/, :profile => /#{Noosfero.identifier_format_in_url}/, :as => :tag_feed
74 74
75 # profile tags 75 # profile tags
76 - match 'profile/:profile/tags/:id', :controller => 'profile', :action => 'content_tagged', :id => /.+/, :profile => /#{Noosfero.identifier_format}/  
77 - match 'profile/:profile/tags(/:id)', :controller => 'profile', :action => 'tags', :profile => /#{Noosfero.identifier_format}/ 76 + match 'profile/:profile/tags/:id', :controller => 'profile', :action => 'content_tagged', :id => /.+/, :profile => /#{Noosfero.identifier_format_in_url}/
  77 + match 'profile/:profile/tags(/:id)', :controller => 'profile', :action => 'tags', :profile => /#{Noosfero.identifier_format_in_url}/
78 78
79 # profile search 79 # profile search
80 - match 'profile/:profile/search', :controller => 'profile_search', :action => 'index', :profile => /#{Noosfero.identifier_format}/ 80 + match 'profile/:profile/search', :controller => 'profile_search', :action => 'index', :profile => /#{Noosfero.identifier_format_in_url}/
81 81
82 # comments 82 # comments
83 - match 'profile/:profile/comment/:action/:id', :controller => 'comment', :profile => /#{Noosfero.identifier_format}/ 83 + match 'profile/:profile/comment/:action/:id', :controller => 'comment', :profile => /#{Noosfero.identifier_format_in_url}/
84 84
85 # public profile information 85 # public profile information
86 - match 'profile/:profile(/:action(/:id))', :controller => 'profile', :action => 'index', :id => /[^\/]*/, :profile => /#{Noosfero.identifier_format}/, :as => :profile 86 + match 'profile/:profile(/:action(/:id))', :controller => 'profile', :action => 'index', :id => /[^\/]*/, :profile => /#{Noosfero.identifier_format_in_url}/, :as => :profile
87 87
88 # contact 88 # contact
89 - match 'contact/:profile/:action(/:id)', :controller => 'contact', :action => 'index', :id => /.*/, :profile => /#{Noosfero.identifier_format}/ 89 + match 'contact/:profile/:action(/:id)', :controller => 'contact', :action => 'index', :id => /.*/, :profile => /#{Noosfero.identifier_format_in_url}/
90 90
91 # map balloon 91 # map balloon
92 match 'map_balloon/:action/:id', :controller => 'map_balloon', :id => /.*/ 92 match 'map_balloon/:action/:id', :controller => 'map_balloon', :id => /.*/
@@ -98,8 +98,8 @@ Noosfero::Application.routes.draw do @@ -98,8 +98,8 @@ Noosfero::Application.routes.draw do
98 ## Controllers that are profile-specific (for profile admins ) 98 ## Controllers that are profile-specific (for profile admins )
99 ###################################################### 99 ######################################################
100 # profile customization - "My profile" 100 # profile customization - "My profile"
101 - match 'myprofile/:profile', :controller => 'profile_editor', :action => 'index', :profile => /#{Noosfero.identifier_format}/  
102 - match 'myprofile/:profile/:controller(/:action(/:id))', :controller => Noosfero.pattern_for_controllers_in_directory('my_profile'), :profile => /#{Noosfero.identifier_format}/, :as => :myprofile 101 + match 'myprofile/:profile', :controller => 'profile_editor', :action => 'index', :profile => /#{Noosfero.identifier_format_in_url}/
  102 + match 'myprofile/:profile/:controller(/:action(/:id))', :controller => Noosfero.pattern_for_controllers_in_directory('my_profile'), :profile => /#{Noosfero.identifier_format_in_url}/, :as => :myprofile
103 103
104 104
105 ###################################################### 105 ######################################################
@@ -127,14 +127,14 @@ Noosfero::Application.routes.draw do @@ -127,14 +127,14 @@ Noosfero::Application.routes.draw do
127 # cache stuff - hack 127 # cache stuff - hack
128 match 'public/:action/:id', :controller => 'public' 128 match 'public/:action/:id', :controller => 'public'
129 129
130 - match ':profile/*page/versions', :controller => 'content_viewer', :action => 'article_versions', :profile => /#{Noosfero.identifier_format}/, :constraints => EnvironmentDomainConstraint.new 130 + match ':profile/*page/versions', :controller => 'content_viewer', :action => 'article_versions', :profile => /#{Noosfero.identifier_format_in_url}/, :constraints => EnvironmentDomainConstraint.new
131 match '*page/versions', :controller => 'content_viewer', :action => 'article_versions' 131 match '*page/versions', :controller => 'content_viewer', :action => 'article_versions'
132 132
133 - match ':profile/*page/versions_diff', :controller => 'content_viewer', :action => 'versions_diff', :profile => /#{Noosfero.identifier_format}/, :constraints => EnvironmentDomainConstraint.new 133 + match ':profile/*page/versions_diff', :controller => 'content_viewer', :action => 'versions_diff', :profile => /#{Noosfero.identifier_format_in_url}/, :constraints => EnvironmentDomainConstraint.new
134 match '*page/versions_diff', :controller => 'content_viewer', :action => 'versions_diff' 134 match '*page/versions_diff', :controller => 'content_viewer', :action => 'versions_diff'
135 135
136 # match requests for profiles that don't have a custom domain 136 # match requests for profiles that don't have a custom domain
137 - match ':profile(/*page)', :controller => 'content_viewer', :action => 'view_page', :profile => /#{Noosfero.identifier_format}/, :constraints => EnvironmentDomainConstraint.new 137 + match ':profile(/*page)', :controller => 'content_viewer', :action => 'view_page', :profile => /#{Noosfero.identifier_format_in_url}/, :constraints => EnvironmentDomainConstraint.new
138 138
139 # match requests for content in domains hosted for profiles 139 # match requests for content in domains hosted for profiles
140 match '/(*page)', :controller => 'content_viewer', :action => 'view_page' 140 match '/(*page)', :controller => 'content_viewer', :action => 'view_page'
debian/changelog
  1 +noosfero (1.1) wheezy; urgency=low
  2 +
  3 + * Noosfero 1.1 final release
  4 +
  5 + -- Antonio Terceiro <terceiro@colivre.coop.br> Mon, 04 May 2015 18:47:35 -0300
  6 +
1 noosfero (1.1~rc4) wheezy; urgency=medium 7 noosfero (1.1~rc4) wheezy; urgency=medium
2 8
3 * Fourth release candidate for Noosfero 1.1 9 * Fourth release candidate for Noosfero 1.1
lib/noosfero.rb
@@ -57,6 +57,12 @@ module Noosfero @@ -57,6 +57,12 @@ module Noosfero
57 '[a-z0-9][a-z0-9~.]*([_\-][a-z0-9~.]+)*' 57 '[a-z0-9][a-z0-9~.]*([_\-][a-z0-9~.]+)*'
58 end 58 end
59 59
  60 + # All valid identifiers, plus ~ meaning "the current user". See
  61 + # ApplicationController#redirect_to_current_user
  62 + def self.identifier_format_in_url
  63 + "(#{identifier_format}|~)"
  64 + end
  65 +
60 def self.default_hostname 66 def self.default_hostname
61 Environment.table_exists? && Environment.default ? Environment.default.default_hostname : 'localhost' 67 Environment.table_exists? && Environment.default ? Environment.default.default_hostname : 'localhost'
62 end 68 end
lib/noosfero/version.rb
1 module Noosfero 1 module Noosfero
2 PROJECT = 'noosfero' 2 PROJECT = 'noosfero'
3 - VERSION = '1.1~rc4' 3 + VERSION = '1.1'
4 end 4 end
5 5
6 root = File.expand_path(File.dirname(__FILE__) + '/../..') 6 root = File.expand_path(File.dirname(__FILE__) + '/../..')
lib/tasks/backup.rake
1 -desc "Creates a backup of the user files stored in public/"  
2 -task :backup do  
3 - dirs = Dir.glob('public/images/[0-9][0-9][0-9][0-9]') + ['public/articles', 'public/thumbnails', 'public/user_themes'].select { |d| File.exists?(d) }  
4 - tarball = 'backups/files-' + Time.now.strftime('%Y-%m-%d-%R') + '.tar' 1 +task :load_backup_config do
  2 + $config = YAML.load_file('config/database.yml')
  3 +end
  4 +
  5 +task :check_backup_support => :load_backup_config do
  6 + if $config['production']['adapter'] != 'postgresql'
  7 + fail("Only PostgreSQL is supported for backups at the moment")
  8 + end
  9 +end
  10 +
  11 +backup_dirs = [
  12 + 'public/image_uploads',
  13 + 'public/articles',
  14 + 'public/thumbnails',
  15 + 'public/user_themes',
  16 +]
  17 +
  18 +desc "Creates a backup of the database and uploaded files"
  19 +task :backup => :check_backup_support do
  20 + dirs = backup_dirs.select { |d| File.exists?(d) }
  21 +
  22 + backup_name = Time.now.strftime('%Y-%m-%d-%R')
  23 + backup_file = File.join('tmp/backup', backup_name) + '.tar.gz'
  24 + mkdir_p 'tmp/backup'
  25 + dump = File.join('tmp/backup', backup_name) + '.sql'
  26 +
  27 + database = $config['production']['database']
  28 + host = $config['production']['host']
  29 + sh "pg_dump -h #{host} #{database} > #{dump}"
  30 +
  31 + sh 'tar', 'chaf', backup_file, dump, *dirs
  32 + rm_f dump
  33 +
  34 + puts "****************************************************"
  35 + puts "Backup in #{backup_file} !"
  36 + puts
  37 + puts "To restore, use:"
  38 + puts "$ rake restore BACKUP=#{backup_file}"
  39 + puts "****************************************************"
  40 +end
  41 +
  42 +def invalid_backup!(message, items=[])
  43 + puts "E: #{message}"
  44 + items.each do |i|
  45 + puts "E: - #{i}"
  46 + end
  47 + puts "E: Is this a backup archive created by Noosfero with \`rake backup\`?"
  48 + exit 1
  49 +end
  50 +
  51 +desc "Restores a backup created previousy with \`rake backup\`"
  52 +task :restore => :check_backup_support do
  53 + backup = ENV["BACKUP"]
  54 + unless backup
  55 + puts "usage: rake restore BACKUP=/path/to/backup"
  56 + exit 1
  57 + end
  58 +
  59 + files = `tar taf #{backup}`.split
  60 +
  61 + # validate files in the backup
  62 + invalid_files = []
  63 + files.each do |f|
  64 + if f !~ /tmp\/backup\// && (backup_dirs.none? { |d| f =~ /^#{d}\// })
  65 + invalid_files << f
  66 + end
  67 + end
  68 + if invalid_files.size > 0
  69 + invalid_backup!("Invalid files found in the backup archive", invalid_files)
  70 + end
  71 +
  72 + # find database dump in the archive
  73 + dumps = files.select do |f|
  74 + File.dirname(f) == 'tmp/backup' && f =~ /\.sql$/
  75 + end
  76 + if dumps.size == 0
  77 + invalid_backup!("Could not find a database dump in the archive.")
  78 + elsif dumps.size > 1
  79 + invalid_backup!("Multiple database dumps found in the archive:", dumps)
  80 + end
  81 + dump = dumps.first
  82 +
  83 + database = $config['production']['database']
  84 + username = $config['production']['username']
  85 + host = $config['production']['host']
  86 +
  87 + puts "WARNING: backups should be restored to an empty database, otherwise"
  88 + puts "data from the backup may not be loaded properly."
  89 + puts
  90 + puts 'You can remove the existing database and create a new one with:'
  91 + puts
  92 + puts "$ sudo -u postgres dropdb -h #{host} #{database}"
  93 + puts "$ sudo -u postgres createdb -h #{host} #{database} --owner #{username}"
  94 + puts
  95 + print "Are you sure you want to continue (y/N)? "
  96 + response = $stdin.gets.strip
  97 + unless ['y', 'yes'].include?(response.downcase)
  98 + puts "*** ABORTED."
  99 + exit 1
  100 + end
  101 +
  102 + sh 'tar', 'xaf', backup
  103 + sh "rails dbconsole production < #{dump}"
  104 + rm_f dump
5 105
6 - mkdir_p(File.dirname(tarball))  
7 - sh('tar', 'cf', tarball, *dirs) 106 + puts "****************************************************"
  107 + puts "Backup restored!"
  108 + puts "****************************************************"
8 end 109 end
lib/tasks/doc.rake
@@ -12,9 +12,8 @@ namespace :noosfero do @@ -12,9 +12,8 @@ namespace :noosfero do
12 end 12 end
13 end 13 end
14 task :unlink_plugins_textiles do 14 task :unlink_plugins_textiles do
15 - root = Pathname.new(File.dirname(__FILE__) + '/../..').expand_path  
16 - rm_f Dir.glob(root.join('doc/noosfero/plugins/*.textile')) -  
17 - [root.join('doc/noosfero/plugins/index.textile')] 15 + rm_f Dir.glob('doc/noosfero/plugins/*.textile') -
  16 + ['doc/noosfero/plugins/index.textile']
18 end 17 end
19 input = Dir.glob('doc/noosfero/**/*.textile') + plugins_textiles.map{|i| "doc/noosfero/plugins/#{File.basename(i)}"} 18 input = Dir.glob('doc/noosfero/**/*.textile') + plugins_textiles.map{|i| "doc/noosfero/plugins/#{File.basename(i)}"}
20 topics_xhtml = input.map { |item| item.sub('.textile', '.en.xhtml') }.uniq 19 topics_xhtml = input.map { |item| item.sub('.textile', '.en.xhtml') }.uniq
lib/tasks/error_messages.rake
@@ -4,7 +4,7 @@ targets = [] @@ -4,7 +4,7 @@ targets = []
4 templates.each do |template| 4 templates.each do |template|
5 target = template.gsub(/.erb$/, '') 5 target = template.gsub(/.erb$/, '')
6 targets << target 6 targets << target
7 - file target => [:makemo, template] do 7 + file target => [:makemo, template, :environment] do
8 require 'erb' 8 require 'erb'
9 erb = ERB.new(File.read(template)) 9 erb = ERB.new(File.read(template))
10 File.open(target, 'w') do |file| 10 File.open(target, 'w') do |file|
plugins/sub_organizations/db/migrate/20150508153119_add_timestamp_to_relation.rb 0 → 100644
@@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
  1 +class AddTimestampToRelation < ActiveRecord::Migration
  2 + def change
  3 + add_column :sub_organizations_plugin_relations, :created_at, :datetime
  4 + add_column :sub_organizations_plugin_relations, :updated_at, :datetime
  5 + end
  6 +end
plugins/sub_organizations/lib/sub_organizations_plugin/relation.rb
1 class SubOrganizationsPlugin::Relation < Noosfero::Plugin::ActiveRecord 1 class SubOrganizationsPlugin::Relation < Noosfero::Plugin::ActiveRecord
2 - record_timestamps = false  
3 -  
4 belongs_to :parent, :polymorphic => true 2 belongs_to :parent, :polymorphic => true
5 belongs_to :child, :polymorphic => true 3 belongs_to :child, :polymorphic => true
6 4
test/functional/application_controller_test.rb
@@ -578,4 +578,22 @@ class ApplicationControllerTest &lt; ActionController::TestCase @@ -578,4 +578,22 @@ class ApplicationControllerTest &lt; ActionController::TestCase
578 assert_response :success 578 assert_response :success
579 end 579 end
580 580
  581 + should "redirect to 404 if profile is '~' and user is not logged in" do
  582 + get :index, :profile => '~'
  583 + assert_response :missing
  584 + end
  585 +
  586 + should "redirect to action when profile is '~' " do
  587 + login_as('ze')
  588 + get :index, :profile => '~'
  589 + assert_response 302
  590 + end
  591 +
  592 + should "substitute '~' by current user and redirect properly " do
  593 + login_as('ze')
  594 + profile = Profile.where(:identifier => 'ze').first
  595 + get :index, :profile => '~'
  596 + assert_redirected_to :controller => 'test', :action => 'index', :profile => profile.identifier
  597 + end
  598 +
581 end 599 end
test/functional/profile_design_controller_test.rb
@@ -737,9 +737,9 @@ class ProfileDesignControllerTest &lt; ActionController::TestCase @@ -737,9 +737,9 @@ class ProfileDesignControllerTest &lt; ActionController::TestCase
737 end 737 end
738 end 738 end
739 739
740 - test 'should forbid POST to save for fixed blocks' do 740 + test 'should forbid POST to save for uneditable blocks' do
741 block = profile.blocks.last 741 block = profile.blocks.last
742 - block.fixed = true 742 + block.edit_modes = "none"
743 block.save! 743 block.save!
744 744
745 post :save, id: block.id, profile: profile.identifier 745 post :save, id: block.id, profile: profile.identifier
@@ -748,7 +748,7 @@ class ProfileDesignControllerTest &lt; ActionController::TestCase @@ -748,7 +748,7 @@ class ProfileDesignControllerTest &lt; ActionController::TestCase
748 748
749 test 'should forbid POST to move_block for fixed blocks' do 749 test 'should forbid POST to move_block for fixed blocks' do
750 block = profile.blocks.last 750 block = profile.blocks.last
751 - block.fixed = true 751 + block.move_modes = "none"
752 block.save! 752 block.save!
753 753
754 post :move_block, id: block.id, profile: profile.identifier, target: "end-of-box-#{@box3.id}" 754 post :move_block, id: block.id, profile: profile.identifier, target: "end-of-box-#{@box3.id}"
test/integration/routing_test.rb
@@ -272,4 +272,8 @@ class RoutingTest &lt; ActionController::IntegrationTest @@ -272,4 +272,8 @@ class RoutingTest &lt; ActionController::IntegrationTest
272 assert_routing('/embed/block/12345', :controller => 'embed', :action => 'block', :id => '12345') 272 assert_routing('/embed/block/12345', :controller => 'embed', :action => 'block', :id => '12345')
273 end 273 end
274 274
  275 + should 'accept ~ as placeholder for current user' do
  276 + assert_routing('/profile/~', :controller => 'profile', :profile => '~', :action => 'index')
  277 + end
  278 +
275 end 279 end
test/unit/block_test.rb
@@ -35,6 +35,24 @@ class BlockTest &lt; ActiveSupport::TestCase @@ -35,6 +35,24 @@ class BlockTest &lt; ActiveSupport::TestCase
35 assert Block.new.editable? 35 assert Block.new.editable?
36 end 36 end
37 37
  38 + should 'be editable if edit modes is all' do
  39 + block = Block.new
  40 + block.edit_modes = 'all'
  41 +
  42 + assert block.editable?
  43 + end
  44 +
  45 + should 'be movable by default' do
  46 + assert Block.new.movable?
  47 + end
  48 +
  49 + should 'be movable if move modes is all' do
  50 + block = Block.new
  51 + block.move_modes = 'all'
  52 +
  53 + assert block.movable?
  54 + end
  55 +
38 should 'have default titles' do 56 should 'have default titles' do
39 b = Block.new 57 b = Block.new
40 b.expects(:default_title).returns('my title') 58 b.expects(:default_title).returns('my title')
test/unit/boxes_helper_test.rb
@@ -123,24 +123,24 @@ class BoxesHelperTest &lt; ActionView::TestCase @@ -123,24 +123,24 @@ class BoxesHelperTest &lt; ActionView::TestCase
123 display_box_content(box, '') 123 display_box_content(box, '')
124 end 124 end
125 125
126 - should 'not show move options on block when block is fixed' do 126 + should 'not show move options on block when block has no permission to edit' do
127 p = create_user_with_blocks 127 p = create_user_with_blocks
128 128
129 b = p.blocks.select{|bk| !bk.kind_of?(MainBlock) }[0] 129 b = p.blocks.select{|bk| !bk.kind_of?(MainBlock) }[0]
130 - b.fixed = true 130 + b.move_modes = "none"
131 b.save! 131 b.save!
132 132
133 stubs(:environment).returns(p.environment) 133 stubs(:environment).returns(p.environment)
134 stubs(:user).returns(p) 134 stubs(:user).returns(p)
135 135
136 - assert_equal false, modifiable?(b) 136 + assert_equal false, movable?(b)
137 end 137 end
138 138
139 - should 'show move options on block when block is fixed and user is admin' do 139 + should 'show move options on block when block has no permission to edit and user is admin' do
140 p = create_user_with_blocks 140 p = create_user_with_blocks
141 141
142 b = p.blocks.select{|bk| !bk.kind_of?(MainBlock) }[0] 142 b = p.blocks.select{|bk| !bk.kind_of?(MainBlock) }[0]
143 - b.fixed = true 143 + b.edit_modes = "none"
144 b.save! 144 b.save!
145 145
146 p.environment.add_admin(p) 146 p.environment.add_admin(p)
@@ -148,7 +148,7 @@ class BoxesHelperTest &lt; ActionView::TestCase @@ -148,7 +148,7 @@ class BoxesHelperTest &lt; ActionView::TestCase
148 stubs(:environment).returns(p.environment) 148 stubs(:environment).returns(p.environment)
149 stubs(:user).returns(p) 149 stubs(:user).returns(p)
150 150
151 - assert_equal true, modifiable?(b) 151 + assert_equal true, movable?(b)
152 end 152 end
153 153
154 should 'consider boxes_limit without custom_design' do 154 should 'consider boxes_limit without custom_design' do
@@ -198,4 +198,16 @@ class BoxesHelperTest &lt; ActionView::TestCase @@ -198,4 +198,16 @@ class BoxesHelperTest &lt; ActionView::TestCase
198 assert_no_tag_in_string block_edit_buttons(block), :tag => 'a', :attributes => {:class => 'button icon-button icon-embed '} 198 assert_no_tag_in_string block_edit_buttons(block), :tag => 'a', :attributes => {:class => 'button icon-button icon-embed '}
199 end 199 end
200 200
  201 + should 'only show edit option on block' do
  202 + p = create_user_with_blocks
  203 +
  204 + b = p.blocks.select{|bk| !bk.kind_of?(MainBlock) }[0]
  205 + b.edit_modes = "only_edit"
  206 + b.save!
  207 +
  208 + stubs(:environment).returns(p.environment)
  209 + stubs(:user).returns(p)
  210 +
  211 + assert_equal false, b.editable?
  212 + end
201 end 213 end
test/unit/user_test.rb
@@ -554,6 +554,7 @@ class UserTest &lt; ActiveSupport::TestCase @@ -554,6 +554,7 @@ class UserTest &lt; ActiveSupport::TestCase
554 554
555 should 'delay activation check with custom time' do 555 should 'delay activation check with custom time' do
556 NOOSFERO_CONF.stubs(:[]).with('hours_until_user_activation_check').returns(240) 556 NOOSFERO_CONF.stubs(:[]).with('hours_until_user_activation_check').returns(240)
  557 + NOOSFERO_CONF.stubs(:[]).with('exclude_profile_identifier_pattern')
557 user = new_user 558 user = new_user
558 job = Delayed::Job.last 559 job = Delayed::Job.last
559 assert_match /UserActivationJob/, job.handler 560 assert_match /UserActivationJob/, job.handler