Commit 7a8c628278b97de5e019a31467c24924126515ae

Authored by Evandro Junior
2 parents 256e490d 99b738b5

Merge branch 'master' of gitlab.com:noosfero/noosfero

Showing 94 changed files with 1352 additions and 426 deletions   Show diff stats
INSTALL.chat.md
1   -XMPP/Chat Setup
2   -===============
  1 +Automatic XMPP/Chat Setup
  2 +=========================
  3 +
  4 +Since Noosfero 1.2, the XMPP/Chat can be installed via `noosfero-chat` Debian
  5 +package. So you don't need to follow the manual instructions here if you
  6 +already have it installed on your system.
  7 +
  8 +But if you are going to install the `noosfero-chat` package on a system that
  9 +already has `noosfero` older 1.2 installed then you need to check if apache's
  10 +configuration file `/etc/apache2/sites-available/noosfero` has this line below:
  11 +
  12 + Include /usr/share/noosfero/util/chat/apache/xmpp.conf
  13 +
  14 +Manual XMPP/Chat Setup
  15 +======================
3 16  
4 17 The samples of config file to configure a XMPP/BOSH server with ejabberd,
5 18 postgresql and apache2 can be found at util/chat directory.
... ... @@ -8,7 +21,7 @@ This setup supposes that you are using Noosfero installed via Debian package
8 21 in a production environment.
9 22  
10 23 Steps
11   -=====
  24 +-----
12 25  
13 26 This is a step-by-step guide to get a XMPP service working, in a Debian system.
14 27  
... ... @@ -144,15 +157,8 @@ You should see a page with a message like that:
144 157  
145 158 ## 9. Test chat session
146 159  
147   -Open Noosfero console and execute:
148   -
149   ->> environment = Environment.default
150   ->> user = Person['guest']
151   ->> password = user.user.crypted_password
152   ->> login = user.jid
153   ->> RubyBOSH.initialize_session(login, password, "http://#{environment.default_hostname}/http-bind", :wait => 30, :hold => 1, :window => 5
154   -
155   -If you have luck, should see something like that:
  160 +Run `./script/noosfero-test-chat-session`. If you have luck, should see
  161 +something like that:
156 162  
157 163 Ruby-BOSH - SEND
158 164 <body window="5" rid="60265" xmlns="http://jabber.org/protocol/httpbind" xmlns:xmpp="urn:xmpp:xbosh" to="vagrant-debian-squeeze.vagrantup.com" wait="30" xmpp:version="1.0" hold="1"/>
... ...
app/controllers/admin/admin_panel_controller.rb
... ... @@ -71,22 +71,4 @@ class AdminPanelController &lt; AdminController
71 71 end
72 72 end
73 73 end
74   -
75   - def manage_organizations_status
76   - scope = environment.organizations
77   - @filter = params[:filter] || 'any'
78   - @title = "Organization profiles"
79   - @title = @title+" - "+@filter if @filter != 'any'
80   -
81   - if @filter == 'enabled'
82   - scope = scope.visible
83   - elsif @filter == 'disabled'
84   - scope = scope.disabled
85   - end
86   -
87   - scope = scope.order('name ASC')
88   -
89   - @q = params[:q]
90   - @collection = find_by_contents(:organizations, environment, scope, @q, {:per_page => 10, :page => params[:npage]})[:results]
91   - end
92 74 end
... ...
app/controllers/admin/organizations_controller.rb 0 → 100644
... ... @@ -0,0 +1,66 @@
  1 +class OrganizationsController < AdminController
  2 +
  3 + protect 'manage_environment_organizations', :environment
  4 +
  5 + def index
  6 + @filter = params[:filter] || 'any'
  7 + @title = _('Organization profiles')
  8 + @type = params[:type] || "any"
  9 + @types_filter = [[_('All'), 'any'], [_('Community'), 'Community'], [_('Enterprise'), 'Enterprise']]
  10 + @types_filter = @types_filter | @plugins.dispatch(:organization_types_filter_options)
  11 +
  12 + scope = @plugins.dispatch_first(:filter_manage_organization_scope, @type)
  13 + if scope.blank?
  14 + scope = environment.organizations
  15 + scope = scope.where(:type => @type) if @type != 'any'
  16 + end
  17 +
  18 + if @filter == 'enabled'
  19 + scope = scope.visible
  20 + elsif @filter == 'disabled'
  21 + scope = scope.disabled
  22 + end
  23 +
  24 + scope = scope.order('name ASC')
  25 +
  26 + @q = params[:q]
  27 + @collection = find_by_contents(:organizations, environment, scope, @q, {:per_page => per_page, :page => params[:npage]})[:results]
  28 + end
  29 +
  30 + def activate
  31 + organization = environment.organizations.find(params[:id])
  32 + if organization.enable
  33 + render :text => (_('%s enabled') % organization.name).to_json
  34 + else
  35 + render :text => (_('%s could not be enabled') % organization.name).to_json
  36 + end
  37 + end
  38 +
  39 + def deactivate
  40 + organization = environment.organizations.find(params[:id])
  41 + if organization.disable
  42 + render :text => (_('%s disabled') % organization.name).to_json
  43 + else
  44 + render :text => (_('%s could not be disable') % organization.name).to_json
  45 + end
  46 + end
  47 +
  48 + def destroy
  49 + if request.post?
  50 + organization = environment.organizations.find(params[:id])
  51 + if organization && organization.destroy
  52 + render :text => (_('%s removed') % organization.name).to_json
  53 + else
  54 + render :text => (_('%s could not be removed') % organization.name).to_json
  55 + end
  56 + else
  57 + render :nothing => true
  58 + end
  59 + end
  60 +
  61 + private
  62 +
  63 + def per_page
  64 + 10
  65 + end
  66 +end
... ...
app/controllers/my_profile/cms_controller.rb
... ... @@ -143,7 +143,14 @@ class CmsController &lt; MyProfileController
143 143 klass = @type.constantize
144 144 article_data = environment.enabled?('articles_dont_accept_comments_by_default') ? { :accept_comments => false } : {}
145 145 article_data.merge!(params[:article]) if params[:article]
146   - @article = klass.new(article_data)
  146 + article_data.merge!(:profile => profile) if profile
  147 +
  148 + @article = if params[:clone]
  149 + current_article = profile.articles.find(params[:id])
  150 + current_article.copy_without_save
  151 + else
  152 + klass.new(article_data)
  153 + end
147 154  
148 155 parent = check_parent(params[:parent_id])
149 156 if parent
... ... @@ -220,7 +227,7 @@ class CmsController &lt; MyProfileController
220 227 if @errors.any?
221 228 render :action => 'upload_files', :parent_id => @parent_id
222 229 else
223   - session[:notice] = _('File(s) successfully uploaded')
  230 + session[:notice] = _('File(s) successfully uploaded')
224 231 if @back_to
225 232 redirect_to @back_to
226 233 elsif @parent
... ...
app/controllers/my_profile/tasks_controller.rb
1 1 class TasksController < MyProfileController
2 2  
3 3 protect 'perform_task', :profile
4   -
  4 +
5 5 def index
6   - @filter = params[:filter_type].blank? ? nil : params[:filter_type]
  6 + @filter_type = params[:filter_type].presence
  7 + @filter_text = params[:filter_text].presence
7 8 @task_types = Task.pending_types_for(profile)
8   - @tasks = Task.to(profile).without_spam.pending.of(@filter).order_by('created_at', 'asc').paginate(:per_page => Task.per_page, :page => params[:page])
  9 + @tasks = Task.pending_all(profile, @filter_type, @filter_text).order_by('created_at', 'asc').paginate(:per_page => Task.per_page, :page => params[:page])
9 10 @failed = params ? params[:failed] : {}
10 11 end
11 12  
... ...
app/controllers/public/content_viewer_controller.rb
... ... @@ -13,7 +13,7 @@ class ContentViewerController &lt; ApplicationController
13 13 @version = params[:version].to_i
14 14  
15 15 if path.blank?
16   - @page = profile.home_page
  16 + @page = profile.home_page
17 17 return if redirected_to_profile_index
18 18 else
19 19 @page = profile.articles.find_by_path(path)
... ... @@ -121,21 +121,23 @@ class ContentViewerController &lt; ApplicationController
121 121 helper_method :pass_without_comment_captcha?
122 122  
123 123 def allow_access_to_page(path)
124   - allowed = true
125 124 if @page.nil? # page not found, give error
126 125 render_not_found(path)
127   - allowed = false
128   - elsif !@page.display_to?(user)
129   - if !profile.public?
  126 + return false
  127 + end
  128 +
  129 + unless @page.display_to?(user)
  130 + if !profile.visible? || profile.secret? || (user && user.follows?(profile))
  131 + render_access_denied
  132 + else #!profile.public?
130 133 private_profile_partial_parameters
131 134 render :template => 'profile/_private_profile', :status => 403, :formats => [:html]
132   - allowed = false
133   - else #if !profile.visible?
134   - render_access_denied
135   - allowed = false
136 135 end
  136 +
  137 + return false
137 138 end
138   - allowed
  139 +
  140 + return true
139 141 end
140 142  
141 143 def user_is_a_bot?
... ... @@ -180,7 +182,7 @@ class ContentViewerController &lt; ApplicationController
180 182 if @page.forum? && @page.has_terms_of_use && terms_accepted == "true"
181 183 @page.add_agreed_user(user)
182 184 end
183   - end
  185 + end
184 186  
185 187 def is_a_forum_topic? (page)
186 188 return (!@page.parent.nil? && @page.parent.forum?)
... ...
app/controllers/public_controller.rb
... ... @@ -3,7 +3,7 @@ class PublicController &lt; ApplicationController
3 3  
4 4 def allow_access_to_page
5 5 unless profile.display_info_to?(user)
6   - if profile.visible?
  6 + if profile.visible? && !profile.secret
7 7 private_profile
8 8 else
9 9 invisible_profile
... ...
app/helpers/application_helper.rb
... ... @@ -931,6 +931,19 @@ module ApplicationHelper
931 931 article_helper.cms_label_for_edit
932 932 end
933 933  
  934 + def label_for_clone_article(article)
  935 + translated_types = {
  936 + Folder => _('Folder'),
  937 + Blog => _('Blog'),
  938 + Event => _('Event'),
  939 + Forum => _('Forum')
  940 + }
  941 +
  942 + translated_type = translated_types[article.class] || _('Article')
  943 +
  944 + _('Clone %s') % translated_type
  945 + end
  946 +
934 947 def add_rss_feed_to_head(title, url)
935 948 content_for :feeds do
936 949 tag(:link, :rel => 'alternate', :type => 'application/rss+xml', :title => title, :href => url_for(url))
... ... @@ -1498,4 +1511,26 @@ module ApplicationHelper
1498 1511 text_field(object_name, method, options.merge(:class => 'colorpicker_field'))
1499 1512 end
1500 1513  
  1514 + def fullscreen_buttons(itemId)
  1515 + content="
  1516 + <script>fullscreenPageLoad('#{itemId}')</script>
  1517 + "
  1518 + content+=content_tag('a', content_tag('span',_("Full screen")),
  1519 + { :id=>"fullscreen-btn",
  1520 + :onClick=>"toggle_fullwidth('#{itemId}')",
  1521 + :class=>"button with-text icon-fullscreen",
  1522 + :href=>"#",
  1523 + :title=>_("Go to full screen mode")
  1524 + })
  1525 +
  1526 + content+=content_tag('a', content_tag('span',_("Exit full screen")),
  1527 + { :style=>"display: none;",
  1528 + :id=>"exit-fullscreen-btn",
  1529 + :onClick=>"toggle_fullwidth('#{itemId}')",
  1530 + :class=>"button with-text icon-fullscreen",
  1531 + :href=>"#",
  1532 + :title=>_("Exit full screen mode")
  1533 + })
  1534 + end
  1535 +
1501 1536 end
... ...
app/helpers/article_helper.rb
... ... @@ -12,6 +12,7 @@ module ArticleHelper
12 12 @article = article
13 13  
14 14 visibility_options(@article, tokenized_children) +
  15 + topic_creation(@article) +
15 16 content_tag('h4', _('Options')) +
16 17 content_tag('div',
17 18 (article.profile.has_members? ?
... ... @@ -55,14 +56,7 @@ module ArticleHelper
55 56 'div',
56 57 check_box(:article, :display_versions) +
57 58 content_tag('label', _('I want this article to display a link to older versions'), :for => 'article_display_versions')
58   - ) : '') +
59   -
60   - (article.forum? && article.profile.community? ?
61   - content_tag(
62   - 'div',
63   - check_box(:article, :allows_members_to_create_topics) +
64   - content_tag('label', _('Allow members to create topics'), :for => 'article_allows_members_to_create_topics')
65   - ) : '')
  59 + ) : '')
66 60 )
67 61 end
68 62  
... ... @@ -81,6 +75,22 @@ module ArticleHelper
81 75 )
82 76 end
83 77  
  78 + def topic_creation(article)
  79 + return '' unless article.forum?
  80 +
  81 + general_options = Forum::TopicCreation.general_options(article)
  82 + slider_options = {:id => 'topic-creation-slider'}
  83 + slider_options = general_options.keys.inject(slider_options) do |result, option|
  84 + result.merge!({'data-'+option => general_options[option]})
  85 + end
  86 +
  87 + content_tag('h4', _('Topic creation')) +
  88 + content_tag( 'small', _('Who will be able to create new topics on this forum?')) +
  89 + content_tag('div', '', slider_options) +
  90 + hidden_field_tag('article[topic_creation]', article.topic_creation) +
  91 + javascript_include_tag('topic-creation-config')
  92 + end
  93 +
84 94 def privacity_exceptions(article, tokenized_children)
85 95 content_tag('div',
86 96 content_tag('div',
... ...
app/helpers/tinymce_helper.rb
... ... @@ -20,7 +20,7 @@ module TinymceHelper
20 20 :image_advtab => true,
21 21 :language => tinymce_language
22 22  
23   - options[:toolbar1] = "insertfile undo redo | copy paste | bold italic underline | styleselect fontsizeselect | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image"
  23 + options[:toolbar1] = "fullscreen | insertfile undo redo | copy paste | bold italic underline | styleselect fontsizeselect | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image"
24 24 if options[:mode] == 'simple'
25 25 options[:menubar] = false
26 26 else
... ...
app/helpers/users_helper.rb
... ... @@ -14,7 +14,7 @@ module UsersHelper
14 14 select_field = select_tag(:filter, options, :onchange => onchange)
15 15 content_tag('div',
16 16 content_tag('strong', _('Filter')) + ': ' + select_field,
17   - :class => "environment-users-customize-search"
  17 + :class => "environment-profiles-customize-search"
18 18 )
19 19 end
20 20  
... ...
app/mailers/task_mailer.rb
... ... @@ -5,7 +5,7 @@ class TaskMailer &lt; ActionMailer::Base
5 5 @target = task.target.name
6 6 @environment = task.environment.name
7 7 @url = generate_environment_url(task, :controller => 'home')
8   - url_for_tasks_list = task.target.kind_of?(Environment) ? '' : url_for(task.target.tasks_url)
  8 + url_for_tasks_list = task.target.kind_of?(Environment) ? '' : url_for(task.target.tasks_url.merge(:script_name => Noosfero.root('/')))
9 9 @tasks_url = url_for_tasks_list
10 10  
11 11 mail(
... ... @@ -56,7 +56,7 @@ class TaskMailer &lt; ActionMailer::Base
56 56 end
57 57  
58 58 def generate_environment_url(task, url = {})
59   - url_for(Noosfero.url_options.merge(:host => task.environment.default_hostname).merge(url))
  59 + url_for(Noosfero.url_options.merge(:host => task.environment.default_hostname).merge(url).merge(:script_name => Noosfero.root('/')))
60 60 end
61 61  
62 62 end
... ...
app/models/article.rb
... ... @@ -25,6 +25,16 @@ class Article &lt; ActiveRecord::Base
25 25 :display => %w[full]
26 26 }
27 27  
  28 + def initialize(*params)
  29 + super
  30 +
  31 + if !params.blank? && params.first.has_key?(:profile)
  32 + profile = params.first[:profile]
  33 + self.published = false unless profile.public?
  34 + end
  35 +
  36 + end
  37 +
28 38 def self.default_search_display
29 39 'full'
30 40 end
... ... @@ -491,11 +501,11 @@ class Article &lt; ActiveRecord::Base
491 501 return [] if user.nil? || (profile && !profile.public? && !user.follows?(profile))
492 502 where(
493 503 [
494   - "published = ? OR last_changed_by_id = ? OR profile_id = ? OR ?
495   - OR (show_to_followers = ? AND ?)", true, user.id, user.id,
  504 + "published = ? OR last_changed_by_id = ? OR profile_id = ? OR ?
  505 + OR (show_to_followers = ? AND ? AND profile_id = ?)", true, user.id, user.id,
496 506 profile.nil? ? false : user.has_permission?(:view_private_content, profile),
497   - true, user.follows?(profile)
498   - ]
  507 + true, user.follows?(profile), (profile.nil? ? nil : profile.id)
  508 + ]
499 509 )
500 510 }
501 511  
... ... @@ -509,7 +519,7 @@ class Article &lt; ActiveRecord::Base
509 519  
510 520 def display_to?(user = nil)
511 521 if published?
512   - profile.display_info_to?(user)
  522 + (profile.secret? || !profile.visible?) ? profile.display_info_to?(user) : true
513 523 else
514 524 if !user
515 525 false
... ... @@ -567,25 +577,24 @@ class Article &lt; ActiveRecord::Base
567 577 profile.visible? && profile.public? && published?
568 578 end
569 579  
570   -
571   - def copy(options = {})
  580 + def copy_without_save(options = {})
572 581 attrs = attributes.reject! { |key, value| ATTRIBUTES_NOT_COPIED.include?(key.to_sym) }
573 582 attrs.merge!(options)
574 583 object = self.class.new
575 584 attrs.each do |key, value|
576 585 object.send(key.to_s+'=', value)
577 586 end
  587 + object
  588 + end
  589 +
  590 + def copy(options = {})
  591 + object = copy_without_save(options)
578 592 object.save
579 593 object
580 594 end
581 595  
582 596 def copy!(options = {})
583   - attrs = attributes.reject! { |key, value| ATTRIBUTES_NOT_COPIED.include?(key.to_sym) }
584   - attrs.merge!(options)
585   - object = self.class.new
586   - attrs.each do |key, value|
587   - object.send(key.to_s+'=', value)
588   - end
  597 + object = copy_without_save(options)
589 598 object.save!
590 599 object
591 600 end
... ...
app/models/block.rb
... ... @@ -2,7 +2,7 @@ class Block &lt; ActiveRecord::Base
2 2  
3 3 attr_accessible :title, :display, :limit, :box_id, :posts_per_page,
4 4 :visualization_format, :language, :display_user,
5   - :box, :edit_modes, :move_modes
  5 + :box, :edit_modes, :move_modes, :mirror
6 6  
7 7 # to be able to generate HTML
8 8 include ActionView::Helpers::UrlHelper
... ... @@ -15,11 +15,23 @@ class Block &lt; ActiveRecord::Base
15 15  
16 16 acts_as_list :scope => :box
17 17 belongs_to :box
  18 + belongs_to :mirror_block, :class_name => "Block"
  19 + has_many :observers, :class_name => "Block", :foreign_key => "mirror_block_id"
18 20  
19 21 acts_as_having_settings
20 22  
21 23 scope :enabled, :conditions => { :enabled => true }
22 24  
  25 + after_save do |block|
  26 + if block.owner.kind_of?(Profile) && block.owner.is_template? && block.mirror?
  27 + block.observers.each do |observer|
  28 + observer.copy_from(block)
  29 + observer.title = block.title
  30 + observer.save
  31 + end
  32 + end
  33 + end
  34 +
23 35 def embedable?
24 36 false
25 37 end
... ... @@ -269,6 +281,10 @@ class Block &lt; ActiveRecord::Base
269 281 self.position = block.position
270 282 end
271 283  
  284 + def add_observer(block)
  285 + self.observers << block
  286 + end
  287 +
272 288 private
273 289  
274 290 def home_page_path
... ...
app/models/environment.rb
... ... @@ -29,6 +29,7 @@ class Environment &lt; ActiveRecord::Base
29 29 'manage_environment_roles' => N_('Manage environment roles'),
30 30 'manage_environment_validators' => N_('Manage environment validators'),
31 31 'manage_environment_users' => N_('Manage environment users'),
  32 + 'manage_environment_organizations' => N_('Manage environment organizations'),
32 33 'manage_environment_templates' => N_('Manage environment templates'),
33 34 'manage_environment_licenses' => N_('Manage environment licenses'),
34 35 'manage_environment_trusted_sites' => N_('Manage environment trusted sites'),
... ... @@ -339,6 +340,16 @@ class Environment &lt; ActiveRecord::Base
339 340 self.save!
340 341 end
341 342  
  343 + def enable_all_plugins
  344 + Noosfero::Plugin.available_plugin_names.each do |plugin|
  345 + plugin_name = plugin.to_s + "Plugin"
  346 + unless self.enabled_plugins.include?(plugin_name)
  347 + self.enabled_plugins += [plugin_name]
  348 + end
  349 + end
  350 + self.save!
  351 + end
  352 +
342 353 # Disables a feature identified by its name
343 354 def disable(feature, must_save=true)
344 355 self.settings["#{feature}_enabled".to_sym] = false
... ...
app/models/forum.rb
... ... @@ -3,11 +3,11 @@ class Forum &lt; Folder
3 3 acts_as_having_posts :order => 'updated_at DESC'
4 4 include PostsLimit
5 5  
6   - attr_accessible :has_terms_of_use, :terms_of_use, :allows_members_to_create_topics
  6 + attr_accessible :has_terms_of_use, :terms_of_use, :topic_creation
7 7  
8 8 settings_items :terms_of_use, :type => :string, :default => ""
9 9 settings_items :has_terms_of_use, :type => :boolean, :default => false
10   - settings_items :allows_members_to_create_topics, :type => :boolean, :default => false
  10 + settings_items :topic_creation, :type => :string, :default => 'self'
11 11 has_and_belongs_to_many :users_with_agreement, :class_name => 'Person', :join_table => 'terms_forum_people'
12 12  
13 13 before_save do |forum|
... ... @@ -33,6 +33,23 @@ class Forum &lt; Folder
33 33 _('An internet forum, also called message board, where discussions can be held.')
34 34 end
35 35  
  36 + module TopicCreation
  37 + BASE = ActiveSupport::OrderedHash.new
  38 + BASE['users'] = _('Logged users')
  39 +
  40 + PERSON = ActiveSupport::OrderedHash.new
  41 + PERSON['self'] = _('Me')
  42 + PERSON['related'] = _('Friends')
  43 +
  44 + GROUP = ActiveSupport::OrderedHash.new
  45 + GROUP['self'] = _('Administrators')
  46 + GROUP['related'] = _('Members')
  47 +
  48 + def self.general_options(forum)
  49 + forum.profile.person? ? PERSON.merge(BASE) : GROUP.merge(BASE)
  50 + end
  51 + end
  52 +
36 53 include ActionView::Helpers::TagHelper
37 54 def to_html(options = {})
38 55 proc do
... ... @@ -69,11 +86,17 @@ class Forum &lt; Folder
69 86 self.users_with_agreement.exists? user
70 87 end
71 88  
72   - def can_create_topic?(user, profile)
73   - return profile.community? && profile.members.include?(user) && self.allows_members_to_create_topics
  89 + def can_create_topic?(user)
  90 + return true if user == profile || profile.admins.include?(user) || profile.environment.admins.include?(user)
  91 + case topic_creation
  92 + when 'related'
  93 + profile.person? ? profile.friends.include?(user) : profile.members.include?(user)
  94 + when 'users'
  95 + user.present?
  96 + end
74 97 end
75 98  
76 99 def allow_create?(user)
77   - super || can_create_topic?(user, profile)
  100 + super || can_create_topic?(user)
78 101 end
79 102 end
... ...
app/models/profile.rb
... ... @@ -392,6 +392,9 @@ class Profile &lt; ActiveRecord::Base
392 392 new_block = block.class.new(:title => block[:title])
393 393 new_block.copy_from(block)
394 394 new_box.blocks << new_block
  395 + if block.mirror?
  396 + block.add_observer(new_block)
  397 + end
395 398 end
396 399 end
397 400 end
... ... @@ -957,11 +960,19 @@ private :generate_url, :url_options
957 960 self.save
958 961 end
959 962  
  963 + def disabled?
  964 + !visible
  965 + end
  966 +
960 967 def enable
961 968 self.visible = true
962 969 self.save
963 970 end
964 971  
  972 + def enabled?
  973 + visible
  974 + end
  975 +
965 976 def control_panel_settings_button
966 977 {:title => _('Edit Profile'), :icon => 'edit-profile'}
967 978 end
... ...
app/models/suggest_article.rb
... ... @@ -25,7 +25,7 @@ class SuggestArticle &lt; Task
25 25  
26 26 def article_object
27 27 if @article_object.nil?
28   - @article_object = article_type.new(article.merge({:profile => target}).except(:type))
  28 + @article_object = article_type.new(article.merge(target.present? ? {:profile => target} : {}).except(:type))
29 29 if requestor.present?
30 30 @article_object.author = requestor
31 31 else
... ...
app/models/task.rb
... ... @@ -239,6 +239,10 @@ class Task &lt; ActiveRecord::Base
239 239 scope :opened, :conditions => { :status => [Task::Status::ACTIVE, Task::Status::HIDDEN] }
240 240 scope :of, lambda { |type| conditions = type ? "type LIKE '#{type}'" : "1=1"; {:conditions => [conditions]} }
241 241 scope :order_by, lambda { |attribute, ord| {:order => "#{attribute} #{ord}"} }
  242 + scope :like, lambda { |field, value| where("LOWER(#{field}) LIKE ?", "%#{value.downcase}%") if value}
  243 + scope :pending_all, lambda { |profile, filter_type, filter_text|
  244 + self.to(profile).without_spam.pending.of(filter_type).like('data', filter_text)
  245 + }
242 246  
243 247 scope :to, lambda { |profile|
244 248 environment_condition = nil
... ...
app/views/admin_panel/index.html.erb
... ... @@ -18,9 +18,9 @@
18 18 <table>
19 19 <tr><td><%= link_to _('User roles'), :controller => 'role' %></td></tr>
20 20 <tr><td><%= link_to _('Users'), :controller => 'users' %></td></tr>
  21 + <tr><td><%= link_to _('Organizations'), :controller => 'organizations' %></td></tr>
21 22 <tr><td><%= link_to _('Profile templates'), :controller => 'templates' %></td></tr>
22 23 <tr><td><%= link_to _('Fields'), :controller => 'features', :action => 'manage_fields' %></td></tr>
23   - <tr><td><%= link_to _('Manage organizations status'), :action => 'manage_organizations_status' %></td></tr>
24 24 </table>
25 25  
26 26  
... ...
app/views/admin_panel/manage_organizations_status.html.erb
... ... @@ -1,69 +0,0 @@
1   -<h1><%= _('Manage organizations') %></h1>
2   -
3   -<%= form_tag( { :action => 'manage_organizations_status' }, :method => 'get', :class => 'users-search' ) do %>
4   -
5   - <div class="search-field">
6   - <span class="formfield">
7   - <%= text_field_tag 'q', @q, :title => _("Find profiles"), :style=>"width:85%" %>
8   - </span>
9   -
10   - <%= submit_button(:search, _('Search')) %>
11   - </div>
12   -
13   - <div class="environment-users-results-header">
14   - <div id='environment-users-filter-title'><%= @title %></div>
15   -
16   - <div id="environment-users-filter-filter">
17   - <strong><%= _("Filter by: ") %></strong>
18   -
19   - <select id="profile_filter_select">
20   - <%= options_for_select([['Any', 'any'],["Disabled profiles", "disabled"], ["Enabled profiles", "enabled"]], @filter) %>
21   - </select>
22   - </div>
23   - <div style="clear: both"></div>
24   - </div>
25   -
26   - <table>
27   - <colgroup>
28   - <col width="80%">
29   - <col width="20%">
30   - </colgroup>
31   -
32   - <tr>
33   - <th><%= _('Member') %></th>
34   - <th><%= _('Actions') %></th>
35   - </tr>
36   -
37   - <% @collection.each do |p| %>
38   - <tr title="<%= p.name %>">
39   - <td><%= link_to_profile p.short_name, p.identifier, :title => p.name %> </td>
40   -
41   - <td class='actions'>
42   - <div class="members-buttons-cell">
43   - <% if p.visible %>
44   - <%= button_without_text :'deactivate-user', _('Deactivate'), {:controller => "profile_editor", :action => 'deactivate_profile', :profile => p.identifier, :id => p.id}, :confirm => _("Do you want to deactivate this profile ?") %>
45   - <% else %>
46   - <%= button_without_text :'activate-user', _('Activate'), {:controller => "profile_editor", :action => 'activate_profile', :profile => p.identifier, :id => p.id}, :confirm => _("Do you want to activate this profile ?") %>
47   - <% end %>
48   - <%= button_without_text :'delete', _('Remove'), {:controller => "profile_editor", :action => 'destroy_profile', :profile => p.identifier, :id => p.id, :return_to => "/admin/admin_panel/manage_organizations_status"}, :method => :post, :confirm => _("Do you want to deactivate this profile ?") %>
49   - </div>
50   - </td>
51   - </tr>
52   - <% end %>
53   - </table>
54   -
55   -<% end %>
56   -
57   -<%= pagination_links @collection, {:param_name => 'npage', :page_links => true} %>
58   -
59   -<% button_bar do %>
60   - <%= button :back, _('Back'), :controller => 'admin_panel' %>
61   -<% end %>
62   -
63   -<script type="text/javascript">
64   - jQuery(document).ready(function(){
65   - jQuery("#profile_filter_select").change(function(){
66   - document.location.href = '/admin/admin_panel/manage_organizations_status?filter='+this.value;
67   - });
68   - });
69   -</script>
70 0 \ No newline at end of file
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/box_organizer/edit.html.erb
... ... @@ -25,6 +25,11 @@
25 25 </div>
26 26 <div class="move-modes">
27 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 + <% end %>
  29 +
  30 + <% if @block.owner.kind_of?(Profile) && @block.owner.is_template? %>
  31 + <div class="mirror_block">
  32 + <%= labelled_check_box(_("Mirror"), "block[mirror]", value = "1", checked = @block.mirror) %>
28 33 </div>
29 34 <% end %>
30 35  
... ...
app/views/cms/_forum.html.erb
... ... @@ -2,6 +2,8 @@
2 2  
3 3 <h1><%= _('My Forum') %></h1>
4 4  
  5 +<%= required_fields_message %>
  6 +
5 7 <%= render :file => 'shared/tiny_mce' %>
6 8  
7 9 <%= required f.text_field(:name, :size => '64', :maxlength => 150, :onchange => "updateUrlField(this, 'article_slug')") %>
... ...
app/views/content_viewer/_article_toolbar.html.erb
1 1 <div<%= user && " class='logged-in'" %>>
2 2 <div id="article-actions">
3 3  
  4 + <%= fullscreen_buttons('#article') %>
4 5  
5 6 <% if @page.allow_edit?(user) && !remove_content_button(:edit, @page) %>
6 7 <% content = content_tag('span', label_for_edit_article(@page)) %>
... ... @@ -29,6 +30,10 @@
29 30 <% end %>
30 31  
31 32 <%= modal_button(:new, label_for_new_article(@page), profile.admin_url.merge(:controller => 'cms', :action => 'new', :parent_id => (@page.folder? ? @page : (@page.parent.nil? ? nil : @page.parent)))) unless remove_content_button(:new, @page) %>
  33 +
  34 + <% content = content_tag('span', label_for_clone_article(@page)) %>
  35 + <% url = profile.admin_url.merge({ :controller => 'cms', :action => 'new', :id => @page.id, :clone => true, :type => @page.class }) %>
  36 + <%= expirable_button @page, :clone, content, url %>
32 37 <% end %>
33 38  
34 39 <% if @page.accept_uploads? && @page.allow_create?(user) %>
... ...
app/views/organizations/_results.html.erb 0 → 100644
... ... @@ -0,0 +1,41 @@
  1 +<div class='results'>
  2 + <table id='organizations-list'>
  3 + <colgroup>
  4 + <col width="60%">
  5 + <col width="20%">
  6 + <col width="20%">
  7 + </colgroup>
  8 +
  9 + <tr>
  10 + <th><%= _('Profile') %></th>
  11 + <th><%= _('Actions') %></th>
  12 + <th><%= _('Type') %>
  13 +
  14 + <%= select_tag(:type, options_for_select(@types_filter, @type)) %>
  15 + </th>
  16 + </tr>
  17 +
  18 + <% @collection.each do |p| %>
  19 + <tr title="<%= p.name %>">
  20 + <td><%= link_to_profile p.short_name, p.identifier, :title => p.name %> </td>
  21 +
  22 + <td class='actions'>
  23 + <div class="members-buttons-cell">
  24 + <% if p.visible %>
  25 + <%= button_without_text :'deactivate-user', _('Deactivate'), {:action => 'deactivate', :id => p.id}, :class => 'action', 'data-confirm' => _("Do you want to deactivate this organization?") %>
  26 + <% else %>
  27 + <%= button_without_text :'activate-user', _('Activate'), {:action => 'activate', :id => p.id}, :class => 'action', 'data-confirm' => _("Do you want to activate this organization?") %>
  28 + <% end %>
  29 + <%= button_without_text :'delete', _('Remove'), {:action => 'destroy', :id => p.id}, :class => 'action', 'data-method' => :post, 'data-confirm' => _("Do you want to destroy this organization?") %>
  30 + </div>
  31 + </td>
  32 +
  33 + <td> <%= _("#{p.type}") %> </td>
  34 + </tr>
  35 + <% end %>
  36 + </table>
  37 +
  38 + <div>
  39 + <%= pagination_links @collection, {:param_name => 'npage', :page_links => true} %>
  40 + </div>
  41 +</div>
... ...
app/views/organizations/index.html.erb 0 → 100644
... ... @@ -0,0 +1,30 @@
  1 +<h1><%= _('Organizations') %></h1>
  2 +
  3 +<%= form_tag( { :action => 'index' }, :method => 'get', :id => 'manage-profiles' ) do %>
  4 +
  5 + <div class="search-field">
  6 + <span class="formfield">
  7 + <%= text_field_tag 'q', @q, :title => _('Find organizations'), :style=>"width:85%" %>
  8 + </span>
  9 +
  10 + <%= submit_button(:search, _('Search')) %>
  11 + </div>
  12 +
  13 + <div class="environment-profiles-results-header">
  14 + <div id='environment-profiles-filter-title'><%= @title %></div>
  15 +
  16 + <div id="environment-profiles-filter-filter">
  17 + <strong><%= _("Filter by: ") %></strong>
  18 + <%= select_tag(:filter, options_for_select([[_('Any'), 'any'],[_('Disabled'), "disabled"], [_('Enabled') , "enabled"]], @filter)) %>
  19 + </div>
  20 + <div style="clear: both"></div>
  21 + </div>
  22 +
  23 + <%= render :partial => 'results' %>
  24 +
  25 + <% button_bar do %>
  26 + <%= button :back, _('Back'), :controller => 'admin_panel' %>
  27 + <% end %>
  28 +<% end %>
  29 +
  30 +<%= javascript_include_tag 'manage-organizations' %>
... ...
app/views/organizations/index.js.erb 0 → 120000
... ... @@ -0,0 +1 @@
  1 +../../views/shared/admin/profiles/index.js.rb
0 2 \ No newline at end of file
... ...
app/views/shared/admin/profiles/index.js.rb 0 → 100644
... ... @@ -0,0 +1 @@
  1 +jQuery('#manage-profiles .results').replaceWith('<%= escape_javascript(render 'results') %>');
... ...
app/views/tasks/_task.html.erb
... ... @@ -22,6 +22,8 @@
22 22 %>
23 23 </div><!-- class="task_decisions" -->
24 24  
  25 + <div class="task_date"><%= show_time(task.created_at) %></div>
  26 +
25 27 <%= render :partial => 'task_title', :locals => {:task => task} %>
26 28  
27 29 <div class="task_information">
... ...
app/views/tasks/index.html.erb
... ... @@ -21,11 +21,24 @@
21 21 </div>
22 22 <% end %>
23 23  
  24 +<%= form_tag '#', :method => 'get' do %>
  25 + <%= field_set_tag _('Filter'), :class => 'filter_fields' do %>
  26 + <p>
  27 + <%= labelled_select(_('Type of task')+': ', :filter_type, :first, :last, @filter_type, type_collection, {:id => 'filter-type'}) %>
  28 + </p>
  29 + <p>
  30 + <%= labelled_text_field(_("Text filter")+': ', :filter_text, nil, {:id => 'filter-text',:value => @filter_text}) %>
  31 + </p>
  32 + <p>
  33 + <%= submit_button(:search, _('Search')) %>
  34 + </p>
  35 + <% end %>
  36 +<% end %>
  37 +
24 38 <% if @tasks.empty? %>
25 39 <p>
26   - <%= labelled_select(_('Filter')+': ', :filter_type, :first, :last, @filter, type_collection, :onchange => "document.location.href = '?filter_type='+this.value")%>
  40 + <em><%= _('No pending tasks for %s') % profile.name %></em>
27 41 </p>
28   - <em><%= _('No pending tasks for %s') % profile.name %></em>
29 42 <% else %>
30 43 <%= form_tag :action => 'close' do%>
31 44 <% button_bar do %>
... ... @@ -38,14 +51,12 @@
38 51  
39 52 <ul class='task-list'>
40 53 <p>
41   - <%= labelled_select(_('Filter')+': ', :filter_type, :first, :last, @filter, type_collection, :onchange => "document.location.href = '?filter_type='+this.value") %>
42   - </p>
43   - <p>
44 54 <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "up-set-all-tasks-to") %>
45 55 </p>
46   - <% @tasks.each do |task| %>
47   - <%= render :partial => 'task', :locals => { :task => task } %>
48   - <% end %>
  56 +
  57 + <div class="task_boxes">
  58 + <%= render :partial => 'task', :collection => @tasks %>
  59 + </div>
49 60 <p>
50 61 <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "down-set-all-tasks-to") %>
51 62 </p>
... ...
app/views/users/_users_list.html.erb
1   -<div class="environment-users-results-header">
2   - <div id='environment-users-filter-title'><%= users_filter_title(@filter) %></div>
  1 +<div class="environment-profiles-results-header">
  2 + <div id='environment-profiles-filter-title'><%= users_filter_title(@filter) %></div>
3 3 <%= filter_selector(@filter) %>
4 4 <div style="clear: both"></div>
5 5 </div>
... ...
db/migrate/20150319114233_change_default_content_privacy.rb 0 → 100644
... ... @@ -0,0 +1,19 @@
  1 +class ChangeDefaultContentPrivacy < ActiveRecord::Migration
  2 + def up
  3 + update_sql('UPDATE articles SET published = (1>2), show_to_followers = (1=1)
  4 + FROM profiles WHERE articles.profile_id = profiles.id AND
  5 + NOT profiles.public_profile AND articles.published = (1=1)')
  6 +
  7 + Block.select('blocks.*').joins("INNER JOIN boxes ON blocks.box_id = boxes.id
  8 + INNER JOIN profiles ON boxes.owner_id = profiles.id AND boxes.owner_type = 'Profile'").
  9 + where("NOT profiles.public_profile AND blocks.type != 'MainBlock'").find_each do |block|
  10 + block.display_user = 'followers'
  11 + block.save
  12 + end
  13 + change_column :articles, :show_to_followers, :boolean, :default => true
  14 + end
  15 +
  16 + def down
  17 + say "this migration can't be reverted"
  18 + end
  19 +end
... ...
db/migrate/20150429145001_add_mirror_to_block.rb 0 → 100644
... ... @@ -0,0 +1,15 @@
  1 +class AddMirrorToBlock < ActiveRecord::Migration
  2 + def up
  3 + change_table :blocks do |t|
  4 + t.boolean :mirror, :default => false
  5 + t.references :mirror_block
  6 + t.references :observers
  7 + end
  8 + end
  9 +
  10 + def down
  11 + remove_column :blocks, :mirror
  12 + remove_column :blocks, :mirror_block_id
  13 + remove_column :blocks, :observers_id
  14 + end
  15 +end
... ...
db/migrate/20150513213939_update_topic_creation_configuration.rb 0 → 100644
... ... @@ -0,0 +1,13 @@
  1 +class UpdateTopicCreationConfiguration < ActiveRecord::Migration
  2 + def up
  3 + Forum.where("setting LIKE '%:allows_members_to_create_topics: true%'").find_each do |forum|
  4 + forum.setting.delete(:allows_members_to_create_topics)
  5 + forum.setting.merge!(:topic_creation => 'related')
  6 + forum.save
  7 + end
  8 + end
  9 +
  10 + def down
  11 + say "this migration can't be reverted"
  12 + end
  13 +end
... ...
db/schema.rb
... ... @@ -11,7 +11,7 @@
11 11 #
12 12 # It's strongly recommended to check this file into your version control system.
13 13  
14   -ActiveRecord::Schema.define(:version => 20150408231524) do
  14 +ActiveRecord::Schema.define(:version => 20150513213939) do
15 15  
16 16 create_table "abuse_reports", :force => true do |t|
17 17 t.integer "reporter_id"
... ... @@ -150,7 +150,7 @@ ActiveRecord::Schema.define(:version =&gt; 20150408231524) do
150 150 t.integer "spam_comments_count", :default => 0
151 151 t.integer "author_id"
152 152 t.integer "created_by_id"
153   - t.boolean "show_to_followers", :default => false
  153 + t.boolean "show_to_followers", :default => true
154 154 end
155 155  
156 156 add_index "articles", ["comments_count"], :name => "index_articles_on_comments_count"
... ... @@ -183,10 +183,13 @@ ActiveRecord::Schema.define(:version =&gt; 20150408231524) do
183 183 t.string "type"
184 184 t.text "settings"
185 185 t.integer "position"
186   - t.boolean "enabled", :default => true
  186 + t.boolean "enabled", :default => true
187 187 t.datetime "created_at"
188 188 t.datetime "updated_at"
189 189 t.datetime "fetched_at"
  190 + t.boolean "mirror", :default => false
  191 + t.integer "mirror_block_id"
  192 + t.integer "observers_id"
190 193 end
191 194  
192 195 add_index "blocks", ["box_id"], :name => "index_blocks_on_box_id"
... ...
db/seeds.rb 0 → 100644
... ... @@ -0,0 +1,14 @@
  1 +# This file should contain all the record creation needed to seed the database with its default values.
  2 +# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
  3 +#
  4 +# Examples:
  5 +#
  6 +# cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }])
  7 +# Mayor.create(name: 'Emanuel', city: cities.first)
  8 +
  9 +ENV['RAILS_ENV'] ||= 'development'
  10 +
  11 +# This is for plugins that wants to use seeds.rb
  12 +# Check for example on the Foo plugin
  13 +plugin_seed_dirs = Dir.glob(Rails.root.join('{baseplugins,config/plugins}', '*', 'db', 'seeds.rb'))
  14 +plugin_seed_dirs.each { |path| load path }
... ...
debian/apache2/conf.d/noosfero-chat 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +<IfModule mpm_worker_module>
  2 + StartServers 8
  3 + MinSpareThreads 25
  4 + MaxSpareThreads 75
  5 + ThreadLimit 128
  6 + ThreadsPerChild 128
  7 + MaxClients 2048
  8 + MaxRequestsPerChild 0
  9 +</IfModule>
... ...
debian/changelog
1   -noosfero (1.2~0) UNRELEASED; urgency=medium
  1 +noosfero (1.2~1) UNRELEASED; urgency=medium
2 2  
  3 + [ Antonio Terceiro ]
3 4 * Temporary version in heavy development
4 5  
5   - -- Antonio Terceiro <terceiro@debian.org> Fri, 08 May 2015 16:08:18 -0300
  6 + [ Joenio Costa ]
  7 + * Build noosfero-chat package
  8 +
  9 + -- Joenio Costa <joenio@colivre.coop.br> Mon, 18 May 2015 14:32:21 -0300
6 10  
7 11 noosfero (1.1) wheezy; urgency=low
8 12  
... ...
debian/control
... ... @@ -85,3 +85,14 @@ Description: free web-based platform for social networks (apache frontend)
85 85 .
86 86 This package contains the configuration files needed to run Noosfero with the
87 87 Apache HTTPD server as frontend.
  88 +
  89 +Package: noosfero-chat
  90 +Architecture: all
  91 +Depends: noosfero (>= 1.2), ejabberd, odbc-postgresql, pidgin-data
  92 +Description: free web-based platform for social networks (ejabberd based chat)
  93 + Noosfero is a web platform for social and solidarity economy networks with
  94 + blog, e-Porfolios, CMS, RSS, thematic discussion, events agenda and collective
  95 + inteligence for solidarity economy in the same system.
  96 + .
  97 + This package contains the configuration files needed to run Noosfero with the
  98 + Ejabberd XMPP chat server.
... ...
debian/default/noosfero-chat 0 → 100644
... ... @@ -0,0 +1,2 @@
  1 +POLL=true
  2 +SMP=auto
... ...
debian/noosfero-chat.install 0 → 100644
... ... @@ -0,0 +1,6 @@
  1 +debian/default/noosfero-chat etc/default
  2 +util/chat/ejabberd.cfg etc/ejabberd
  3 +debian/update-noosfero-odbc usr/sbin
  4 +etc/security/limits.d/noosfero-chat.conf etc/security/limits.d
  5 +etc/pam.d/noosfero-chat etc/pam.d
  6 +debian/apache2/conf.d/noosfero-chat etc/apache2/conf.d
... ...
debian/noosfero-chat.postinst 0 → 100644
... ... @@ -0,0 +1,50 @@
  1 +#!/bin/bash
  2 +
  3 +set -e
  4 +
  5 +. /usr/share/debconf/confmodule
  6 +
  7 +echo -n "Fetching noosfero domain ..."
  8 +domain=$(noosfero-runner 'puts Environment.default.default_hostname(true)')
  9 +echo " [domain = $domain]"
  10 +
  11 +ejabberd_config='/etc/ejabberd/ejabberd.cfg'
  12 +if test -f $ejabberd_config; then
  13 + sed -i "s/acl, *\([^,]*\), *{user, *\([^,]*\), *[^}]*/acl, \1, {user, \2, \"$domain\"/" /etc/ejabberd/ejabberd.cfg
  14 + sed -i "s/hosts, *\[[^]]*/hosts, [\"$domain\"/" /etc/ejabberd/ejabberd.cfg
  15 +fi
  16 +
  17 +echo -n 'Fetching noosfero database name ...'
  18 +noosfero_database=$(noosfero-runner 'puts Environment.connection_config[:database]')
  19 +echo " [database = $noosfero_database]"
  20 +
  21 +echo 'Creating ejabberd schema ...'
  22 +. /etc/default/noosfero
  23 +noosfero_user="$NOOSFERO_USER"
  24 +su - postgres -c "psql -c 'GRANT CREATE ON DATABASE $noosfero_database TO $noosfero_user;' > /dev/null"
  25 +su - $noosfero_user -c 'rails dbconsole production < /usr/share/noosfero/util/chat/postgresql/ejabberd.sql > /dev/null'
  26 +
  27 +if which update-noosfero-odbc > /dev/null ; then
  28 + update-noosfero-odbc
  29 +fi
  30 +
  31 +ejabberd_default='/etc/default/ejabberd'
  32 +noosfero_chat_default='/etc/default/noosfero-chat'
  33 +if test -f $ejabberd_default; then
  34 + if ! cat $ejabberd_default | grep "^\. $noosfero_chat_default" > /dev/null ; then
  35 + echo 'Extending ejabberd defaults with noosfero-chat defaults ...'
  36 + echo ". $noosfero_chat_default" >> $ejabberd_default
  37 + fi
  38 +fi
  39 +
  40 +a2enmod proxy_http
  41 +
  42 +invoke-rc.d ejabberd restart
  43 +invoke-rc.d noosfero restart
  44 +invoke-rc.d apache2 restart
  45 +
  46 +# stop debconf to avoid the problem with infinite hanging, cfe
  47 +# http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=295477
  48 +db_stop
  49 +
  50 +#DEBHELPER#
... ...
debian/noosfero-runner 0 → 100755
... ... @@ -0,0 +1,8 @@
  1 +#!/bin/sh
  2 +
  3 +set -e
  4 +
  5 +environment="$2"
  6 +test -z "$environment" && environment=production
  7 +
  8 +su - noosfero -c "rails runner -e $environment '$1'"
... ...
debian/noosfero.install
... ... @@ -17,6 +17,7 @@ debian/dbupgrade usr/lib/noosfero
17 17 debian/default/noosfero etc/default
18 18 debian/noosfero-check-dbconfig usr/sbin
19 19 debian/noosfero-console usr/sbin
  20 +debian/noosfero-runner usr/sbin
20 21 debian/noosfero.yml etc/noosfero
21 22 debian/thin.yml etc/noosfero
22 23 doc usr/share/noosfero
... ...
debian/update-noosfero-odbc 0 → 100755
... ... @@ -0,0 +1,14 @@
  1 +#!/bin/sh
  2 +
  3 +set -e
  4 +
  5 +# automatically update configuration, but if package noosfero is also installed
  6 +if test -x /usr/share/noosfero/script/odbcconf; then
  7 + config_file="/etc/odbc.ini"
  8 + if test -e "$config_file"; then
  9 + echo "Overwriting $config_file ..."
  10 + fi
  11 + /usr/share/noosfero/script/odbcconf > "$config_file"
  12 +
  13 + echo 'Noosfero ODBC configuration updated.'
  14 +fi
... ...
etc/pam.d/noosfero-chat 0 → 100644
... ... @@ -0,0 +1 @@
  1 +session required pam_limits.so
... ...
etc/security/limits.d/noosfero-chat.conf 0 → 100644
... ... @@ -0,0 +1,2 @@
  1 +ejabberd hard nofile 65536
  2 +ejabberd soft nofile 65536
... ...
features/article_versioning.feature
... ... @@ -80,8 +80,8 @@ Feature: article versioning
80 80  
81 81 Scenario: deny access to specific version when disabled, private and not logged
82 82 Given the article "Edited Article" is updated with
83   - | display_versions | published |
84   - | false | false |
  83 + | display_versions | published | show_to_followers |
  84 + | false | false | false |
85 85 And I am not logged in
86 86 And I go to /joaosilva/edited-article?version=1
87 87 Then I should see "Access denied"
... ...
features/edit_article.feature
... ... @@ -41,6 +41,7 @@ Feature: edit article
41 41 When I follow "Folder"
42 42 And I fill in "Title" with "My Folder"
43 43 And I choose "article_published_false"
  44 + And I uncheck "article_show_to_followers"
44 45 And I press "Save"
45 46 And I log off
46 47 And I go to /freesoftware/my-folder
... ... @@ -87,6 +88,7 @@ Feature: edit article
87 88 When I follow "Folder"
88 89 And I fill in "Title" with "My Folder"
89 90 And I choose "article_published_false"
  91 + And I uncheck "article_show_to_followers"
90 92 Then I should see "Fill in the search field to add the exception users to see this content"
91 93  
92 94 @selenium
... ...
features/forum.feature
... ... @@ -169,124 +169,3 @@ Feature: forum
169 169 | Post one | joaosilva | Hi all | Hi all |
170 170 When I go to /joaosilva/forum
171 171 Then I should see "Joao Silva" within ".forum-post-last-answer"
172   -
173   - @selenium
174   - Scenario: community member should be able to see the discussion topic button
175   - Given the following community
176   - | identifier | name | owner |
177   - | sample-community | Sample Community | joaosilva |
178   - And the following forums
179   - | owner | name |
180   - | sample-community | Forum |
181   - And the following users
182   - | login | name |
183   - | mariasilva | Maria Silva|
184   - And "Maria Silva" is a member of "Sample Community"
185   - And I am logged in as "joaosilva"
186   - When I go to /sample-community/forum
187   - And I follow "Configure forum"
188   - And I check "Allow members to create topics"
189   - And I press "Save"
190   - And I am logged in as "mariasilva"
191   - And I go to /sample-community/forum
192   - Then I should see "New discussion topic"
193   -
194   - @selenium
195   - Scenario: a non community member should not be able to see the discussion topic button
196   - Given the following community
197   - | identifier | name | owner |
198   - | sample-community | Sample Community | joaosilva |
199   - And the following forums
200   - | owner | name |
201   - | sample-community | Forum |
202   - And the following users
203   - | login | name |
204   - | mariasilva | Maria Silva|
205   - And I am logged in as "joaosilva"
206   - When I go to /sample-community/forum
207   - And I follow "Configure forum"
208   - And I check "Allow members to create topics"
209   - And I press "Save"
210   - And I am logged in as "mariasilva"
211   - And I go to /sample-community/forum
212   - Then I should not see "New discussion topic"
213   -
214   - @selenium
215   - Scenario: community member should not be able to see the discussion topic button
216   - Given the following community
217   - | identifier | name | owner |
218   - | sample-community | Sample Community | joaosilva |
219   - And the following forums
220   - | owner | name |
221   - | sample-community | Forum |
222   - And the following users
223   - | login | name |
224   - | mariasilva | Maria Silva|
225   - And "Maria Silva" is a member of "Sample Community"
226   - And I am logged in as "joaosilva"
227   - When I go to /sample-community/forum
228   - And I follow "Configure forum"
229   - And I uncheck "Allow members to create topics"
230   - And I press "Save"
231   - And I am logged in as "mariasilva"
232   - And I go to /sample-community/forum
233   - Then I should not see "New discussion topic"
234   -
235   - @selenium
236   - Scenario: community member should be able to create a topic with the discussion topic button
237   - Given the following community
238   - | identifier | name | owner |
239   - | sample-community | Sample Community | joaosilva |
240   - And the following forums
241   - | owner | name |
242   - | sample-community | Forum |
243   - And the following users
244   - | login | name |
245   - | mariasilva | Maria Silva|
246   - And "Maria Silva" is a member of "Sample Community"
247   - And I am logged in as "joaosilva"
248   - When I go to /sample-community/forum
249   - And I follow "Configure forum"
250   - And I check "Allow members to create topics"
251   - And I press "Save"
252   - And I am logged in as "mariasilva"
253   - And I go to /sample-community/forum
254   - And I follow "New discussion topic"
255   - And I should see "Text article with visual editor"
256   - And I follow "Text article with visual editor"
257   - And I fill in "Title" with "Test"
258   - And I press "Save"
259   - Then I should see "Test"
260   -
261   - @selenium
262   - Scenario: community member should be able to create a topic on a topic page
263   - Given the following community
264   - | identifier | name | owner |
265   - | sample-community | Sample Community | joaosilva |
266   - And the following forums
267   - | owner | name |
268   - | sample-community | Forum |
269   - And the following users
270   - | login | name |
271   - | mariasilva | Maria Silva|
272   - And "Maria Silva" is a member of "Sample Community"
273   - And I am logged in as "joaosilva"
274   - When I go to /sample-community/forum
275   - And I follow "Configure forum"
276   - And I check "Allow members to create topics"
277   - And I press "Save"
278   - And I am logged in as "mariasilva"
279   - And I go to /sample-community/forum
280   - And I follow "New discussion topic"
281   - And I should see "Text article with visual editor"
282   - And I follow "Text article with visual editor"
283   - And I fill in "Title" with "Test"
284   - And I press "Save"
285   - And I go to /sample-community/forum/test
286   - And I follow "New discussion topic"
287   - And I should see "Text article with visual editor"
288   - And I follow "Text article with visual editor"
289   - And I fill in "Title" with "Test inside the topic page"
290   - And I press "Save"
291   - And I go to /sample-community/forum
292   - Then I should see "Test inside the topic page"
... ...
features/secret_community.feature
... ... @@ -33,7 +33,7 @@ Feature: Use a secret community
33 33 Scenario: Non members shouldn't see secret communit's content
34 34 Given I am logged in as "maria"
35 35 And I go to mycommunity's homepage
36   - And I should see "Access denied"
  36 + And I should see "Oops ... you cannot go ahead here"
37 37 And I follow "Communities"
38 38 Then I should not see "My Community"
39 39  
... ...
features/template_block_management.feature 0 → 100644
... ... @@ -0,0 +1,64 @@
  1 +Feature: user template
  2 + As an user
  3 + I want to create templates with mirror blocks
  4 + In order to keep these blocks always updated
  5 +
  6 + Background:
  7 + Given the following users
  8 + | login | name | is_template |
  9 + | person | person | true |
  10 + And the following blocks
  11 + | owner | type | mirror |
  12 + | person | ArticleBlock | true |
  13 + | person | RawHTMLBlock | false |
  14 + And I go to /account/signup
  15 + And I fill in "Username" with "mario"
  16 + And I fill in "Password" with "123456"
  17 + And I fill in "Password confirmation" with "123456"
  18 + And I fill in "e-Mail" with "mario@mario.com"
  19 + And I fill in "Full name" with "Mario"
  20 + And wait for the captcha signup time
  21 + And I press "Create my account"
  22 + And I am logged in as admin
  23 +
  24 + @selenium
  25 + Scenario: The block Article name is changed
  26 + Given I am on person's control panel
  27 + And I follow "Edit sideboxes"
  28 + And display ".button-bar"
  29 + And I follow "Edit" within ".article-block"
  30 + And I fill in "Custom title for this block:" with "Mirror"
  31 + And I press "Save"
  32 + And I go to /profile/mario
  33 + Then I should see "Mirror"
  34 +
  35 + @selenium
  36 + Scenario: The block LinkList is changed but the user's block doesnt change
  37 + Given I am on person's control panel
  38 + And I follow "Edit sideboxes"
  39 + And display ".button-bar"
  40 + And I follow "Edit" within ".raw-html-block"
  41 + And I fill in "Custom title for this block:" with "Raw HTML Block"
  42 + And I press "Save"
  43 + And I go to /profile/mario
  44 + Then I should not see "Raw HTML Block"
  45 +
  46 + @selenium
  47 + Scenario: The block Article cannot move or modify
  48 + Given I am on person's control panel
  49 + And I follow "Edit sideboxes"
  50 + And display ".button-bar"
  51 + And I follow "Edit" within ".article-block"
  52 + And I select "Cannot be moved" from "Move options:"
  53 + And I select "Cannot be modified" from "Edit options:"
  54 + And I press "Save"
  55 + And I follow "Logout"
  56 + And Mario's account is activated
  57 + And I follow "Login"
  58 + And I fill in "Username / Email" with "mario"
  59 + And I fill in "Password" with "123456"
  60 + And I press "Log in"
  61 + And I go to /myprofile/mario
  62 + And I follow "Edit sideboxes"
  63 + And display ".button-bar"
  64 + Then I should not see "Edit" within ".article-block"
... ...
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/plugin.rb
... ... @@ -299,6 +299,18 @@ class Noosfero::Plugin
299 299 nil
300 300 end
301 301  
  302 + # -> Filters the types of organizations that are shown on manage organizations
  303 + # returns a scope filtered by the specified type
  304 + def filter_manage_organization_scope type
  305 + nil
  306 + end
  307 +
  308 + # -> Add new options for manage organization filters
  309 + # returns an array of new options
  310 + # i.e [[_('Type'), 'type'], [_('Type2'), 'type2']]
  311 + def organization_types_filter_options
  312 + nil
  313 + end
302 314 # -> Adds content to profile editor info and settings
303 315 # returns = lambda block that creates html code or raw rhtml/html.erb
304 316 def profile_editor_extras
... ...
lib/tasks/enable_plugins.rake 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +namespace :noosfero do
  2 + namespace :plugins do
  3 + task :enable_all => :environment do
  4 + Environment.all.each do |env|
  5 + puts "Plugins Activated on #{env.name}" if env.enable_all_plugins
  6 + end
  7 + end
  8 + end
  9 +end
... ...
plugins/foo/db/seeds.rb 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +# This file should contain all the record creation needed to seed the database with its default values.
  2 +# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
  3 +#
  4 +# Examples:
  5 +#
  6 +# cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }])
  7 +# Mayor.create(name: 'Emanuel', city: cities.first)
  8 +
  9 +FooPlugin::Bar.create()
... ...
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/tolerance_time/lib/tolerance_time_plugin.rb
... ... @@ -56,9 +56,18 @@ class ToleranceTimePlugin &lt; Noosfero::Plugin
56 56 end
57 57  
58 58 def content_expire_edit(content)
  59 + content_expire_for(content, _('editing'))
  60 + end
  61 +
  62 + def content_expire_clone(content)
  63 + content_expire_for(content, _('cloning'))
  64 + end
  65 +
  66 + private
  67 +
  68 + def content_expire_for(content, action)
59 69 if ToleranceTimePlugin.expired?(content)
60   - _('The tolerance time for editing this content is over.')
  70 + _('The tolerance time for %s this content is over.') % action
61 71 end
62 72 end
63   -
64 73 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/icons/tango/style.css
... ... @@ -114,6 +114,7 @@
114 114 .icon-set-admin-role { background-image: url(mod/16x16/apps/user.png) }
115 115 .icon-reset-admin-role { background-image: url(../../../images/icons-app/person-icon.png) }
116 116 .icon-clock { background-image: url(Tango/16x16/actions/appointment.png) }
  117 +.icon-fullscreen { background-image: url(Tango/16x16/actions/view-fullscreen.png) }
117 118  
118 119 /******************LARGE ICONS********************/
119 120 .image-gallery-item .folder { background-image: url(mod/96x96/places/folder.png) }
... ...
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
... ... @@ -1164,3 +1165,35 @@ function add_new_file_fields() {
1164 1165 }
1165 1166  
1166 1167 window.isHidden = function isHidden() { return (typeof(document.hidden) != 'undefined') ? document.hidden : !document.hasFocus() };
  1168 +
  1169 +function $_GET(id){
  1170 + var a = new RegExp(id+"=([^&#=]*)");
  1171 + return decodeURIComponent(a.exec(window.location.search)[1]);
  1172 +}
  1173 +
  1174 +var fullwidth=false;
  1175 +function toggle_fullwidth(itemId){
  1176 + if(fullwidth){
  1177 + jQuery(itemId).removeClass("fullwidth");
  1178 + jQuery("#fullscreen-btn").show()
  1179 + jQuery("#exit-fullscreen-btn").hide()
  1180 + fullwidth = false;
  1181 + }
  1182 + else{
  1183 + jQuery(itemId).addClass("fullwidth");
  1184 + jQuery("#exit-fullscreen-btn").show()
  1185 + jQuery("#fullscreen-btn").hide()
  1186 + fullwidth = true;
  1187 + }
  1188 + jQuery(window).trigger("toggleFullwidth", fullwidth);
  1189 +}
  1190 +
  1191 +function fullscreenPageLoad(itemId){
  1192 + jQuery(document).ready(function(){
  1193 +
  1194 + if ($_GET('fullscreen') == 1){
  1195 + toggle_fullwidth(itemId);
  1196 + }
  1197 + });
  1198 +}
  1199 +
... ...
public/javascripts/manage-organizations.js 0 → 100644
... ... @@ -0,0 +1,49 @@
  1 +(function($) {
  2 + // Pagination
  3 + $('#manage-profiles').on('click', '.pagination a', function () {
  4 + $.ajax({
  5 + url: this.href,
  6 + beforeSend: function(){$('#manage-profiles .results').addClass('fetching')},
  7 + complete: function() {$('#manage-profiles .results').removeClass('fetching')},
  8 + dataType: 'script'
  9 + })
  10 + return false;
  11 + });
  12 +
  13 + // Actions
  14 + $('#manage-profiles').on('click', '.action', function () {
  15 + if(confirm($(this).data('confirm'))) {
  16 + $.ajax({
  17 + url: this.href,
  18 + method: $(this).data('method') || 'get',
  19 + dataType: 'script',
  20 + success: function(data){
  21 + if(data)
  22 + display_notice(JSON.parse(data));
  23 + },
  24 + error: function(xhr, textStatus, message){
  25 + display_notice(message);
  26 + }
  27 + });
  28 + $('#manage-profiles').submit();
  29 + }
  30 + return false;
  31 + });
  32 +
  33 + // Sorting and Views
  34 + $('#manage-profiles select').live('change', function(){
  35 + $('#manage-profiles').submit();
  36 + });
  37 +
  38 + // Form Ajax submission
  39 + $('#manage-profiles').submit(function () {
  40 + $.ajax({
  41 + url: this.action,
  42 + data: $(this).serialize(),
  43 + beforeSend: function(){$('#manage-profiles .results').addClass('fetching')},
  44 + complete: function() {$('#manage-profiles .results').removeClass('fetching')},
  45 + dataType: 'script'
  46 + })
  47 + return false;
  48 + });
  49 +})(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/javascripts/topic-creation-config.js 0 → 100644
... ... @@ -0,0 +1,30 @@
  1 +var values_map = {2: 'self', 1: 'related', 0: 'users'};
  2 +var keys_map = {};
  3 +Object.keys(values_map).forEach(function(value){
  4 + keys_map[values_map[value]] = value;
  5 +});
  6 +var s = jQuery('#topic-creation-slider');
  7 +
  8 +function setValue(event, ui){
  9 + jQuery('#article_topic_creation').val(values_map[ui.value]);
  10 +}
  11 +
  12 +s.slider({
  13 + orientation: 'vertical',
  14 + min: 0,
  15 + max: 2,
  16 + step: 1,
  17 + value: keys_map[jQuery('#article_topic_creation').val()],
  18 + range: 'max',
  19 + change: setValue
  20 +}).each(function() {
  21 + var opt = jQuery(this).data()['ui-slider'].options;
  22 + var vals = opt.max - opt.min;
  23 +
  24 + for (var i = 0; i <= vals; i++) {
  25 + var n = vals - i;
  26 + var el = jQuery('<label>' + s.data(values_map[i]) + '</label>').css('top', ((n/vals*100) - 7 - n) + '%');
  27 + s.append(el);
  28 + }
  29 +});
  30 +
... ...
public/stylesheets/application.css
... ... @@ -4763,7 +4763,7 @@ h1#agenda-title {
4763 4763 float: right;
4764 4764 }
4765 4765  
4766   -#environment-users-search form {
  4766 +#environment-profiles-search form {
4767 4767 padding: 10px;
4768 4768 margin-bottom: 15px;
4769 4769 background-color: #E6E6E6;
... ... @@ -4771,14 +4771,14 @@ h1#agenda-title {
4771 4771 -webkit-border-radius: 5px;
4772 4772 }
4773 4773  
4774   -.environment-users-results-header {
  4774 +.environment-profiles-results-header {
4775 4775 font-size: 0.9em;
4776 4776 padding: 6px 0px 0px 0px;
4777 4777 margin:0 0 5px 0;
4778 4778 border-bottom: 2px dotted #999;
4779 4779 text-align: right;
4780 4780 }
4781   -#environment-users-filter-title {
  4781 +#environment-profiles-filter-title {
4782 4782 font-weight: bold;
4783 4783 font-size: 130%;
4784 4784 line-height: 35px;
... ... @@ -6239,6 +6239,20 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img {
6239 6239 .forum-posts .pagination {
6240 6240 margin-top: 20px;
6241 6241 }
  6242 +
  6243 +#topic-creation-slider{
  6244 + margin-top: 15px;
  6245 +}
  6246 +
  6247 +#topic-creation-slider .ui-slider-range {
  6248 + background: #73D216;
  6249 +}
  6250 +
  6251 +#topic-creation-slider label {
  6252 + left: 20px;
  6253 + position: absolute;
  6254 + width: 200px;
  6255 +}
6242 6256 /* Task */
6243 6257  
6244 6258 #user a#pending-tasks-count {
... ... @@ -6971,3 +6985,19 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img {
6971 6985 body .ui-widget-overlay {
6972 6986 background: #000;
6973 6987 }
  6988 +
  6989 +.fullwidth{
  6990 + position: fixed !important;
  6991 + left: 0 !important;
  6992 + top: 0 !important;
  6993 + background: white !important;
  6994 + width: 97% !important;
  6995 + width: 100% !important;
  6996 + z-index: 999 !important;
  6997 + padding: 2em !important;
  6998 + bottom:0 !important;
  6999 + overflow: auto !important;
  7000 + -webkit-box-sizing: border-box !important;
  7001 + -moz-box-sizing: border-box !important;
  7002 + box-sizing: border-box !important;
  7003 +}
... ...
public/stylesheets/tasks.css
... ... @@ -17,6 +17,11 @@
17 17 font-size: 120%;
18 18 }
19 19  
  20 +.task_date {
  21 + color: gray;
  22 + font-size: 12px;
  23 +}
  24 +
20 25 .task_icon {
21 26 float: left;
22 27 margin-right: 10px;
... ...
script/apacheconf
... ... @@ -32,6 +32,7 @@ when &#39;virtualhosts&#39;
32 32 puts " #{server_directive} #{domain.name}"
33 33 server_directive = 'ServerAlias'
34 34 end
  35 + puts " Include /usr/share/noosfero/util/chat/apache/xmpp.conf"
35 36 puts " Include /etc/noosfero/apache/virtualhost.conf"
36 37 puts "</VirtualHost>"
37 38 end
... ...
script/noosfero-test-chat-session 0 → 100755
... ... @@ -0,0 +1,28 @@
  1 +#!/usr/bin/env ruby
  2 +require File.dirname(__FILE__) + '/../config/environment'
  3 +
  4 +environment = Environment.default
  5 +person = Person.first
  6 +password = person.user.crypted_password
  7 +login = person.jid
  8 +
  9 +begin
  10 + RubyBOSH.initialize_session(
  11 + login,
  12 + password,
  13 + "http://#{environment.default_hostname}/http-bind",
  14 + :wait => 30,
  15 + :hold => 1,
  16 + :window => 5
  17 + )
  18 +rescue Exception => e
  19 + puts ""
  20 + puts "[ERROR] XMPP/Chat setup isn't working"
  21 + puts "-------------------------------------"
  22 + puts e.to_s
  23 + exit 1
  24 +else
  25 + puts ""
  26 + puts "[OK] XMPP/Chat setup is working"
  27 + exit 0
  28 +end
... ...
script/odbcconf 0 → 100755
... ... @@ -0,0 +1,22 @@
  1 +#!/usr/bin/env ruby
  2 +
  3 +require 'yaml'
  4 +config = YAML.load_file(File.dirname(__FILE__) + '/../config/database.yml')['production']
  5 +
  6 +
  7 +puts "[PostgreSQLEjabberdNoosfero]"
  8 +puts "Description = PostgreSQL Noosfero ejabberd database"
  9 +puts "Driver = PostgreSQL Unicode"
  10 +puts "Trace = No"
  11 +puts "TraceFile = /tmp/psqlodbc.log"
  12 +puts "Database = #{config['database']}"
  13 +puts "Servername = #{config['host'] || 'localhost'}"
  14 +puts "UserName = #{config['username']}"
  15 +puts "Password = #{config['password']}"
  16 +puts "Port = #{config['port'] || '5432'}"
  17 +puts "ReadOnly = No"
  18 +puts "RowVersioning = No"
  19 +puts "ShowSystemTables = No"
  20 +puts "ShowOidColumn = No"
  21 +puts "FakeOidIndex = No"
  22 +puts "ConnSettings = SET search_path TO ejabberd"
... ...
test/factories.rb
... ... @@ -65,7 +65,7 @@ module Noosfero::Factory
65 65 ###### old stuff to be rearranged
66 66 def create_admin_user(env)
67 67 admin_user = User.find_by_login('adminuser') || create_user('adminuser', :email => 'adminuser@noosfero.org', :password => 'adminuser', :password_confirmation => 'adminuser', :environment => env)
68   - admin_role = Role.find_by_name('admin_role') || Role.create!(:name => 'admin_role', :permissions => ['view_environment_admin_panel','edit_environment_features', 'edit_environment_design', 'manage_environment_categories', 'manage_environment_roles', 'manage_environment_trusted_sites', 'manage_environment_validators', 'manage_environment_users', 'manage_environment_templates', 'manage_environment_licenses', 'edit_appearance'])
  68 + admin_role = Role.find_by_name('admin_role') || Role.create!(:name => 'admin_role', :permissions => ['view_environment_admin_panel','edit_environment_features', 'edit_environment_design', 'manage_environment_categories', 'manage_environment_roles', 'manage_environment_trusted_sites', 'manage_environment_validators', 'manage_environment_users', 'manage_environment_organizations', 'manage_environment_templates', 'manage_environment_licenses', 'edit_appearance'])
69 69 create(RoleAssignment, :accessor => admin_user.person, :role => admin_role, :resource => env) unless admin_user.person.role_assignments.map{|ra|[ra.role, ra.accessor, ra.resource]}.include?([admin_role, admin_user, env])
70 70 admin_user.login
71 71 end
... ...
test/fixtures/roles.yml
... ... @@ -35,6 +35,7 @@ four:
35 35 - moderate_comments
36 36 - perform_task
37 37 - manage_environment_users
  38 + - manage_environment_organizations
38 39 - manage_environment_templates
39 40 - manage_environment_licenses
40 41 profile_admin:
... ... @@ -94,6 +95,7 @@ environment_administrator:
94 95 - manage_environment_validators
95 96 - moderate_comments
96 97 - manage_environment_users
  98 + - manage_environment_organizations
97 99 - edit_profile
98 100 - destroy_profile
99 101 - manage_environment_templates
... ...
test/functional/admin_panel_controller_test.rb
... ... @@ -17,12 +17,12 @@ class AdminPanelControllerTest &lt; ActionController::TestCase
17 17 should 'manage the correct environment' do
18 18 current = fast_create(Environment, :name => 'test environment', :is_default => false)
19 19 current.domains.create!(:name => 'example.com')
20   -
  20 +
21 21 @request.expects(:host).returns('example.com').at_least_once
22 22 get :index
23 23 assert_equal current, assigns(:environment)
24 24 end
25   -
  25 +
26 26 should 'link to site_info editing page' do
27 27 get :index
28 28 assert_tag :tag => 'a', :attributes => { :href => '/admin/admin_panel/site_info' }
... ... @@ -379,36 +379,4 @@ class AdminPanelControllerTest &lt; ActionController::TestCase
379 379 assert_equal body, Environment.default.signup_welcome_screen_body
380 380 assert !Environment.default.signup_welcome_screen_body.blank?
381 381 end
382   -
383   - should 'show list to deactivate organizations' do
384   - enabled_community = fast_create(Community, :environment_id => Environment.default, :name=>"enabled community")
385   - disabled_community = fast_create(Community, :environment_id => Environment.default, :name=>"disabled community")
386   - user = create_user('user')
387   -
388   - disabled_community.disable
389   -
390   - Environment.default.add_admin user.person
391   - login_as('user')
392   -
393   - get :manage_organizations_status, :filter=>"enabled"
394   - assert_match(/Organization profiles - enabled/, @response.body)
395   - assert_match(/enabled community/, @response.body)
396   - assert_not_match(/disabled community/, @response.body)
397   - end
398   -
399   - should 'show list to activate organizations' do
400   - enabled_community = fast_create(Community, :environment_id => Environment.default, :name=>"enabled community")
401   - disabled_community = fast_create(Community, :environment_id => Environment.default, :name=>"disabled community")
402   - user = create_user('user')
403   -
404   - disabled_community.disable
405   -
406   - Environment.default.add_admin user.person
407   - login_as('user')
408   -
409   - get :manage_organizations_status, :filter=>"disabled"
410   - assert_match(/Organization profiles - disabled/, @response.body)
411   - assert_not_match(/enabled community/, @response.body)
412   - assert_match(/disabled community/, @response.body)
413   - end
414 382 end
... ...
test/functional/cms_controller_test.rb
... ... @@ -1811,6 +1811,14 @@ class CmsControllerTest &lt; ActionController::TestCase
1811 1811 assert_equal 'first version', assigns(:article).name
1812 1812 end
1813 1813  
  1814 + should 'clone article with its content' do
  1815 + article = profile.articles.create(:name => 'first version')
  1816 +
  1817 + get :new, :profile => profile.identifier, :id => article.id, :clone => true, :type => 'TinyMceArticle'
  1818 +
  1819 + assert_match article.name, @response.body
  1820 + end
  1821 +
1814 1822 should 'save article with content from older version' do
1815 1823 article = profile.articles.create(:name => 'first version')
1816 1824 article.name = 'second version'; article.save
... ...
test/functional/contact_controller_test.rb
... ... @@ -131,7 +131,7 @@ class ContactControllerTest &lt; ActionController::TestCase
131 131 post :new, :profile => community.identifier
132 132  
133 133 assert_response :forbidden
134   - assert_template :private_profile
  134 + assert_template "profile/_private_profile"
135 135 end
136 136  
137 137 should 'not show send e-mail page to non members of invisible community' do
... ...
test/functional/content_viewer_controller_test.rb
... ... @@ -257,22 +257,22 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
257 257 end
258 258  
259 259 should 'not give access to private articles if logged off' do
260   - profile = Profile.create!(:name => 'test profile', :identifier => 'test_profile')
  260 + profile = Community.create!(:name => 'test profile', :identifier => 'test_profile')
261 261 intranet = Folder.create!(:name => 'my_intranet', :profile => profile, :published => false)
262 262  
263 263 get :view_page, :profile => 'test_profile', :page => [ 'my-intranet' ]
264 264  
265   - assert_template 'access_denied'
  265 + assert_template "profile/_private_profile"
266 266 end
267 267  
268 268 should 'not give access to private articles if logged in but not member' do
269 269 login_as('testinguser')
270   - profile = Profile.create!(:name => 'test profile', :identifier => 'test_profile')
  270 + profile = Community.create!(:name => 'test profile', :identifier => 'test_profile')
271 271 intranet = Folder.create!(:name => 'my_intranet', :profile => profile, :published => false)
272 272  
273 273 get :view_page, :profile => 'test_profile', :page => [ 'my-intranet' ]
274 274  
275   - assert_template 'access_denied'
  275 + assert_template "profile/_private_profile"
276 276 end
277 277  
278 278 should 'not give access to private articles if logged in and only member' do
... ... @@ -1252,9 +1252,11 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
1252 1252 should 'expire article actions button if any plugins says so' do
1253 1253 class Plugin1 < Noosfero::Plugin
1254 1254 def content_expire_edit(content); 'This button is expired.'; end
  1255 + def content_expire_clone(content); 'This button is expired.'; end
1255 1256 end
1256 1257 class Plugin2 < Noosfero::Plugin
1257 1258 def content_expire_edit(content); nil; end
  1259 + def content_expire_clone(content); nil; end
1258 1260 end
1259 1261 Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
1260 1262  
... ... @@ -1428,7 +1430,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
1428 1430  
1429 1431 article = TinyMceArticle.create(:name => 'Article to be shared with images',
1430 1432 :body => 'This article should be shared with all social networks',
1431   - :profile => @profile,
  1433 + :profile => community,
1432 1434 :published => false,
1433 1435 :show_to_followers => true)
1434 1436 article.parent = blog
... ...
test/functional/events_controller_test.rb
... ... @@ -60,7 +60,7 @@ class EventsControllerTest &lt; ActionController::TestCase
60 60 post :events, :profile => community.identifier
61 61  
62 62 assert_response :forbidden
63   - assert_template :private_profile
  63 + assert_template "profile/_private_profile"
64 64 end
65 65  
66 66 should 'not show events page to non members of invisible community' do
... ...
test/functional/organizations_controller_test.rb 0 → 100644
... ... @@ -0,0 +1,116 @@
  1 +require_relative "../test_helper"
  2 +require 'organizations_controller'
  3 +
  4 +# Re-raise errors caught by the controller.
  5 +class OrganizationsController; def rescue_action(e) raise e end; end
  6 +
  7 +class OrganizationsControllerTest < ActionController::TestCase
  8 +
  9 + def setup
  10 + @controller = OrganizationsController.new
  11 + @request = ActionController::TestRequest.new
  12 + @response = ActionController::TestResponse.new
  13 +
  14 + Environment.destroy_all
  15 + @environment = fast_create(Environment, :is_default => true)
  16 +
  17 + admin_user = create_user_with_permission('adminuser', 'manage_environment_organizations', environment)
  18 + login_as('adminuser')
  19 + end
  20 +
  21 + attr_accessor :environment
  22 +
  23 + should 'not access without right permission' do
  24 + create_user('guest')
  25 + login_as 'guest'
  26 + get :index
  27 + assert_response 403 # forbidden
  28 + end
  29 +
  30 + should 'grant access with right permission' do
  31 + get :index
  32 + assert_response :success
  33 + end
  34 +
  35 + should 'show list to deactivate organizations' do
  36 + enabled_community = fast_create(Community, :environment_id => Environment.default, :name=>"enabled community")
  37 + disabled_community = fast_create(Community, :environment_id => Environment.default, :name=>"disabled community")
  38 + disabled_community.disable
  39 +
  40 + get :index, :filter => 'enabled'
  41 +
  42 + assert_match(/enabled community/, @response.body)
  43 + assert_not_match(/disabled community/, @response.body)
  44 + end
  45 +
  46 + should 'show list to activate organizations' do
  47 + enabled_community = fast_create(Community, :environment_id => Environment.default, :name=>"enabled community")
  48 + disabled_community = fast_create(Community, :environment_id => Environment.default, :name=>"disabled community")
  49 + disabled_community.disable
  50 +
  51 + get :index, :filter => 'disabled'
  52 +
  53 + assert_not_match(/enabled community/, @response.body)
  54 + assert_match(/disabled community/, @response.body)
  55 + end
  56 +
  57 + should 'show list only of enterprises' do
  58 + community = fast_create(Community, :environment_id => Environment.default, :name=>"Community Test")
  59 + enterprise = fast_create(Enterprise, :environment_id => Environment.default, :name=>"Enterprise Test")
  60 +
  61 + get :index, :type => 'Enterprise'
  62 +
  63 + assert_match(/Enterprise Test/, @response.body)
  64 + assert_not_match(/Community Test/, @response.body)
  65 + end
  66 +
  67 + should 'show list only of communities' do
  68 + community = fast_create(Community, :environment_id => Environment.default, :name=>"Community Test")
  69 + enterprise = fast_create(Enterprise, :environment_id => Environment.default, :name=>"Enterprise Test")
  70 +
  71 + get :index, :type => 'Community'
  72 +
  73 + assert_not_match(/Enterprise Test/, @response.body)
  74 + assert_match(/Community Test/, @response.body)
  75 + end
  76 +
  77 + should 'show list all organizations' do
  78 + community = fast_create(Community, :environment_id => Environment.default, :name=>"Community Test")
  79 + enterprise = fast_create(Enterprise, :environment_id => Environment.default, :name=>"Enterprise Test")
  80 +
  81 + get :index, :type => 'any'
  82 +
  83 + assert_match(/Enterprise Test/, @response.body)
  84 + assert_match(/Community Test/, @response.body)
  85 + end
  86 +
  87 + should 'activate organization profile' do
  88 + organization = fast_create(Organization, :visible => false, :environment_id => environment.id)
  89 + assert organization.disabled?
  90 +
  91 + get :activate, {:id => organization.id}
  92 + organization.reload
  93 +
  94 + assert organization.enabled?
  95 + end
  96 +
  97 + should 'deactivate organization profile' do
  98 + organization = fast_create(Organization, :visible => true, :environment_id => environment.id)
  99 + assert organization.enabled?
  100 +
  101 + get :deactivate, {:id => organization.id}
  102 + organization.reload
  103 +
  104 + assert organization.disabled?
  105 + end
  106 +
  107 + should 'destroy organization profile' do
  108 + organization = fast_create(Organization, :environment_id => environment.id)
  109 +
  110 + post :destroy, {:id => organization.id}
  111 +
  112 + assert_raise ActiveRecord::RecordNotFound do
  113 + organization.reload
  114 + end
  115 + end
  116 +end
... ...
test/functional/profile_editor_controller_test.rb
... ... @@ -1152,57 +1152,4 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase
1152 1152 get :index, :profile => user.identifier
1153 1153 assert_tag :tag => 'div', :descendant => { :tag => 'a', :content => 'Edit Header and Footer' }
1154 1154 end
1155   -
1156   - should 'deactivate organization profile' do
1157   - @request.env['HTTP_REFERER'] = 'http://localhost:3000/admin/admin_panel/manage_organizations_status'
1158   - user = create_user('user').person
1159   - Environment.default.add_admin user
1160   - login_as('user')
1161   -
1162   - community = fast_create(Community)
1163   - assert_equal true, community.enable
1164   -
1165   - get :index, :profile => community.identifier
1166   - get :deactivate_profile, {:profile => community.identifier, :id => community.id}
1167   - assert_equal @request.session[:notice], "The profile '#{community.name}' was deactivated."
1168   - end
1169   -
1170   - should 'activate organization profile' do
1171   - @request.env['HTTP_REFERER'] = 'http://localhost:3000/admin/admin_panel/manage_organizations_status'
1172   - user = create_user('user').person
1173   - Environment.default.add_admin user
1174   - login_as('user')
1175   -
1176   - community = fast_create(Community)
1177   - assert_equal true, community.disable
1178   -
1179   - get :index, :profile => community.identifier
1180   - get :activate_profile, {:profile => community.identifier, :id => community.id}
1181   - assert_equal @request.session[:notice], "The profile '#{community.name}' was activated."
1182   - end
1183   -
1184   - should 'not deactivate organization profile if user is not an admin' do
1185   - @request.env['HTTP_REFERER'] = 'http://localhost:3000/admin/admin_panel/manage_organizations_status'
1186   - user = create_user('user').person
1187   - login_as('user')
1188   -
1189   - community = fast_create(Community)
1190   - get :index, :profile => community.identifier
1191   - get :deactivate_profile, {:profile => community.identifier, :id => community.id}
1192   - assert_not_equal @request.session[:notice], "The profile '#{community.name}' was disabled."
1193   - end
1194   -
1195   - should 'destroy organization profile' do
1196   - @request.env['HTTP_REFERER'] = 'http://localhost:3000/admin/admin_panel/manage_organizations_status'
1197   - user = create_user('user').person
1198   - Environment.default.add_admin user
1199   - login_as('user')
1200   -
1201   - community = fast_create(Community)
1202   - assert_equal true, community.enable
1203   -
1204   - get :index, :profile => community.identifier
1205   - post :destroy_profile, {:profile => community.identifier, :id => community.id}
1206   - assert_equal @request.session[:notice], "The profile was deleted."
1207   - end
1208 1155 end
... ...
test/functional/tasks_controller_test.rb
... ... @@ -5,7 +5,7 @@ class TasksController; def rescue_action(e) raise e end; end
5 5  
6 6 class TasksControllerTest < ActionController::TestCase
7 7  
8   - noosfero_test :profile => 'testuser'
  8 + noosfero_test :profile => 'testuser'
9 9  
10 10 def setup
11 11 @controller = TasksController.new
... ... @@ -49,6 +49,12 @@ class TasksControllerTest &lt; ActionController::TestCase
49 49 assert_kind_of Array, assigns(:tasks)
50 50 end
51 51  
  52 + should 'display task created_at' do
  53 + Task.create!(:requestor => fast_create(Person), :target => profile, :spam => false)
  54 + get :index
  55 + assert_select '.task_date'
  56 + end
  57 +
52 58 should 'list processed tasks without spam' do
53 59 requestor = fast_create(Person)
54 60 task_spam = create(Task, :status => Task::Status::FINISHED, :requestor => requestor, :target => profile, :spam => true)
... ... @@ -388,6 +394,28 @@ class TasksControllerTest &lt; ActionController::TestCase
388 394 assert_includes assigns(:tasks), t3
389 395 end
390 396  
  397 + should 'filter tasks by type and data content' do
  398 + class CleanHouse < Task; end
  399 + class FeedDog < Task; end
  400 + Task.stubs(:per_page).returns(3)
  401 + requestor = fast_create(Person)
  402 + t1 = CleanHouse.create!(:requestor => requestor, :target => profile, :data => {:name => 'Task Test'})
  403 + t2 = CleanHouse.create!(:requestor => requestor, :target => profile)
  404 + t3 = FeedDog.create!(:requestor => requestor, :target => profile)
  405 +
  406 + get :index, :filter_type => t1.type, :filter_text => 'test'
  407 +
  408 + assert_includes assigns(:tasks), t1
  409 + assert_not_includes assigns(:tasks), t2
  410 + assert_not_includes assigns(:tasks), t3
  411 +
  412 + get :index
  413 +
  414 + assert_includes assigns(:tasks), t1
  415 + assert_includes assigns(:tasks), t2
  416 + assert_includes assigns(:tasks), t3
  417 + end
  418 +
391 419 should 'return tasks ordered accordingly and limited by pages' do
392 420 time = Time.now
393 421 person = fast_create(Person)
... ...
test/integration/http_caching_test.rb
... ... @@ -85,7 +85,7 @@ class HttpCachingTest &lt; ActionController::IntegrationTest
85 85  
86 86 test 'private community content should not return cache headers' do
87 87 community = create_private_community('the-community')
88   - create(Article, profile_id: community.id, name: 'Test page')
  88 + create(Article, profile_id: community.id, name: 'Test page', published: false)
89 89  
90 90 get "/the-community/test-page"
91 91 assert_response 403
... ... @@ -139,4 +139,3 @@ class HttpCachingTest &lt; ActionController::IntegrationTest
139 139 end
140 140  
141 141 end
142   -
... ...
test/unit/application_helper_test.rb
... ... @@ -1002,6 +1002,21 @@ class ApplicationHelperTest &lt; ActionView::TestCase
1002 1002 assert_equal file, from_theme_include('atheme', 'afile')[:file] # exists? = true
1003 1003 end
1004 1004  
  1005 + should 'enable fullscreen buttons' do
  1006 + html = fullscreen_buttons("#article")
  1007 + assert html.include?("<script>fullscreenPageLoad('#article')</script>")
  1008 + assert html.include?("class=\"button with-text icon-fullscreen\"")
  1009 + assert html.include?("onClick=\"toggle_fullwidth('#article')\"")
  1010 + end
  1011 +
  1012 + should "return the related class string" do
  1013 + assert_equal "Clone Folder", label_for_clone_article(Folder.new)
  1014 + assert_equal "Clone Blog", label_for_clone_article(Blog.new)
  1015 + assert_equal "Clone Event", label_for_clone_article(Event.new)
  1016 + assert_equal "Clone Forum", label_for_clone_article(Forum.new)
  1017 + assert_equal "Clone Article", label_for_clone_article(TinyMceArticle.new)
  1018 + end
  1019 +
1005 1020 protected
1006 1021 include NoosferoTestHelper
1007 1022  
... ...
test/unit/article_test.rb
... ... @@ -484,7 +484,7 @@ class ArticleTest &lt; ActiveSupport::TestCase
484 484  
485 485 should 'say that member user can not see private article' do
486 486 profile = fast_create(Profile, :name => 'test profile', :identifier => 'test_profile')
487   - article = fast_create(Article, :name => 'test article', :profile_id => profile.id, :published => false)
  487 + article = fast_create(Article, :name => 'test article', :profile_id => profile.id, :published => false, :show_to_followers => false)
488 488 person = create_user('test_user').person
489 489 profile.affiliate(person, Profile::Roles.member(profile.environment.id))
490 490  
... ... @@ -509,15 +509,15 @@ class ArticleTest &lt; ActiveSupport::TestCase
509 509 assert article.display_to?(person)
510 510 end
511 511  
512   - should 'not show article to non member if article public but profile private' do
  512 + should 'show article to non member if article public but profile private' do
513 513 profile = fast_create(Profile, :name => 'test profile', :identifier => 'test_profile', :public_profile => false)
514 514 article = fast_create(Article, :name => 'test article', :profile_id => profile.id, :published => true)
515 515 person1 = create_user('test_user1').person
516 516 profile.affiliate(person1, Profile::Roles.member(profile.environment.id))
517 517 person2 = create_user('test_user2').person
518 518  
519   - assert !article.display_to?(nil)
520   - assert !article.display_to?(person2)
  519 + assert article.display_to?(nil)
  520 + assert article.display_to?(person2)
521 521 assert article.display_to?(person1)
522 522 end
523 523  
... ... @@ -543,7 +543,7 @@ class ArticleTest &lt; ActiveSupport::TestCase
543 543  
544 544 should 'not allow friends of private person see the article' do
545 545 person = create_user('test_user').person
546   - article = create(Article, :name => 'test article', :profile => person, :published => false)
  546 + article = create(Article, :name => 'test article', :profile => person, :published => false, :show_to_followers => false)
547 547 friend = create_user('test_friend').person
548 548 person.add_friend(friend)
549 549 person.save!
... ... @@ -1686,7 +1686,7 @@ class ArticleTest &lt; ActiveSupport::TestCase
1686 1686 a.allow_members_to_edit = true
1687 1687 assert !a.allow_edit?(nil)
1688 1688 end
1689   -
  1689 +
1690 1690 should 'allow author to edit topic' do
1691 1691 community = fast_create(Community)
1692 1692 admin = fast_create(Person)
... ... @@ -1905,7 +1905,7 @@ class ArticleTest &lt; ActiveSupport::TestCase
1905 1905 end
1906 1906  
1907 1907 should 'display_filter display only public articles if there is no user' do
1908   - p = fast_create(Person)
  1908 + p = fast_create(Person)
1909 1909 Article.delete_all
1910 1910 a = fast_create(Article, :published => true, :profile_id => p.id)
1911 1911 fast_create(Article, :published => false, :profile_id => p.id)
... ... @@ -1915,7 +1915,7 @@ class ArticleTest &lt; ActiveSupport::TestCase
1915 1915  
1916 1916 should 'display_filter display public articles for users' do
1917 1917 user = create_user('someuser').person
1918   - p = fast_create(Person)
  1918 + p = fast_create(Person)
1919 1919 user.stubs(:has_permission?).with(:view_private_content, p).returns(false)
1920 1920 Article.delete_all
1921 1921 a = fast_create(Article, :published => true, :profile_id => p.id)
... ... @@ -1926,7 +1926,7 @@ class ArticleTest &lt; ActiveSupport::TestCase
1926 1926  
1927 1927 should 'display_filter display private article last changed by user' do
1928 1928 user = create_user('someuser').person
1929   - p = fast_create(Person)
  1929 + p = fast_create(Person)
1930 1930 user.stubs(:has_permission?).with(:view_private_content, p).returns(false)
1931 1931 Article.delete_all
1932 1932 a = fast_create(Article, :published => false, :last_changed_by_id => user.id, :profile_id => p.id)
... ... @@ -1938,7 +1938,7 @@ class ArticleTest &lt; ActiveSupport::TestCase
1938 1938 should 'display_filter display user private article of his own profile' do
1939 1939 user = create_user('someuser').person
1940 1940 user.stubs(:has_permission?).with(:view_private_content, user).returns(false)
1941   - p = fast_create(Person)
  1941 + p = fast_create(Person)
1942 1942 Article.delete_all
1943 1943 a = fast_create(Article, :published => false, :profile_id => user.id)
1944 1944 fast_create(Article, :published => false, :profile_id => p.id)
... ... @@ -1948,7 +1948,7 @@ class ArticleTest &lt; ActiveSupport::TestCase
1948 1948  
1949 1949 should 'display_filter show profile private content if the user has view_private_content permission' do
1950 1950 user = create_user('someuser').person
1951   - p = fast_create(Person)
  1951 + p = fast_create(Person)
1952 1952 Article.delete_all
1953 1953 user.stubs(:has_permission?).with(:view_private_content, p).returns(false)
1954 1954 a = fast_create(Article, :published => false, :profile_id => p.id)
... ... @@ -1965,8 +1965,8 @@ class ArticleTest &lt; ActiveSupport::TestCase
1965 1965 user.stubs(:has_permission?).with(:view_private_content, p).returns(false)
1966 1966 Article.delete_all
1967 1967 a = fast_create(Article, :published => false, :show_to_followers => true, :profile_id => p.id)
1968   - fast_create(Article, :published => false, :profile_id => p.id)
1969   - fast_create(Article, :published => false, :profile_id => p.id)
  1968 + fast_create(Article, :published => false, :show_to_followers => false, :profile_id => p.id)
  1969 + fast_create(Article, :published => false, :show_to_followers => false, :profile_id => p.id)
1970 1970 assert_equal [a], Article.display_filter(user, p)
1971 1971 end
1972 1972  
... ... @@ -1977,8 +1977,8 @@ class ArticleTest &lt; ActiveSupport::TestCase
1977 1977 user.stubs(:has_permission?).with(:view_private_content, p).returns(false)
1978 1978 Article.delete_all
1979 1979 a = fast_create(Article, :published => false, :show_to_followers => true, :profile_id => p.id)
1980   - fast_create(Article, :published => false, :profile_id => p.id)
1981   - fast_create(Article, :published => false, :profile_id => p.id)
  1980 + fast_create(Article, :published => false, :show_to_followers => false, :profile_id => p.id)
  1981 + fast_create(Article, :published => false, :show_to_followers => false, :profile_id => p.id)
1982 1982 assert_equal [a], Article.display_filter(user, p)
1983 1983 end
1984 1984  
... ... @@ -2040,6 +2040,17 @@ class ArticleTest &lt; ActiveSupport::TestCase
2040 2040 assert_equal [], Article.display_filter(user, nil)
2041 2041 end
2042 2042  
  2043 + should 'display_filter show person public content to non friends passing nil as profile parameter' do
  2044 + user = create_user('someuser').person
  2045 + p = fast_create(Person)
  2046 + assert !p.is_a_friend?(user)
  2047 + assert !user.is_admin?
  2048 + Article.delete_all
  2049 + a1 = fast_create(Article, :profile_id => p.id)
  2050 + a2 = fast_create(Article)
  2051 + assert_equivalent [a1,a2], Article.display_filter(user, nil)
  2052 + end
  2053 +
2043 2054 should 'display_filter do not show community private content to non members passing nil as profile parameter' do
2044 2055 user = create_user('someuser').person
2045 2056 p = fast_create(Community)
... ... @@ -2049,6 +2060,16 @@ class ArticleTest &lt; ActiveSupport::TestCase
2049 2060 assert_equal [], Article.display_filter(user, nil)
2050 2061 end
2051 2062  
  2063 + should 'display_filter show community public content to non members passing nil as profile parameter' do
  2064 + user = create_user('someuser').person
  2065 + p = fast_create(Community)
  2066 + assert !user.is_member_of?(p)
  2067 + Article.delete_all
  2068 + a1 = fast_create(Article, :profile_id => p.id)
  2069 + a2 = fast_create(Article)
  2070 + assert_equivalent [a1,a2], Article.display_filter(user, nil)
  2071 + end
  2072 +
2052 2073 should 'display_filter show community public content of private community for user members' do
2053 2074 user = create_user('someuser').person
2054 2075 p = fast_create(Community, :public_profile => false)
... ... @@ -2057,8 +2078,8 @@ class ArticleTest &lt; ActiveSupport::TestCase
2057 2078 user.stubs(:has_permission?).with(:view_private_content, p).returns(false)
2058 2079 Article.delete_all
2059 2080 a = fast_create(Article, :published => true, :profile_id => p.id)
2060   - fast_create(Article, :published => false, :profile_id => p.id)
2061   - fast_create(Article, :published => false, :profile_id => p.id)
  2081 + fast_create(Article, :published => false, :show_to_followers => false, :profile_id => p.id)
  2082 + fast_create(Article, :published => false, :show_to_followers => false, :profile_id => p.id)
2062 2083 assert_equal [a], Article.display_filter(user, p)
2063 2084 end
2064 2085  
... ... @@ -2088,7 +2109,7 @@ class ArticleTest &lt; ActiveSupport::TestCase
2088 2109 a1 = fast_create(Article, :published => true, :profile_id => user.id)
2089 2110 a2 = fast_create(Article, :published => true, :profile_id => p.id)
2090 2111 fast_create(Article, :published => false, :profile_id => p.id)
2091   - assert_equivalent [a1,a2], Article.display_filter(user, nil)
  2112 + assert_equivalent [a1,a2], Article.display_filter(nil, user)
2092 2113 end
2093 2114  
2094 2115 should 'display_filter show person public content of private person profile for user friends' do
... ... @@ -2099,8 +2120,8 @@ class ArticleTest &lt; ActiveSupport::TestCase
2099 2120 user.stubs(:has_permission?).with(:view_private_content, p).returns(false)
2100 2121 Article.delete_all
2101 2122 a = fast_create(Article, :published => true, :profile_id => p.id)
2102   - fast_create(Article, :published => false, :profile_id => p.id)
2103   - fast_create(Article, :published => false, :profile_id => p.id)
  2123 + fast_create(Article, :published => false, :show_to_followers => false, :profile_id => p.id)
  2124 + fast_create(Article, :published => false, :show_to_followers => false, :profile_id => p.id)
2104 2125 assert_equal [a], Article.display_filter(user, p)
2105 2126 end
2106 2127  
... ... @@ -2130,7 +2151,7 @@ class ArticleTest &lt; ActiveSupport::TestCase
2130 2151 a1 = fast_create(Article, :published => true, :profile_id => user.id)
2131 2152 a2 = fast_create(Article, :published => true, :profile_id => p.id)
2132 2153 fast_create(Article, :published => false, :profile_id => p.id)
2133   - assert_equivalent [a1,a2], Article.display_filter(user, nil)
  2154 + assert_equivalent [a1,a2], Article.display_filter(nil, user)
2134 2155 end
2135 2156  
2136 2157 end
... ...
test/unit/environment_test.rb
... ... @@ -524,7 +524,7 @@ class EnvironmentTest &lt; ActiveSupport::TestCase
524 524 p1= fast_create(Person, :is_template => true, :environment_id => e.id)
525 525 p2 = fast_create(Person, :environment_id => e.id)
526 526 p3 = fast_create(Person, :is_template => true, :environment_id => e.id)
527   - assert_equivalent [p1,p3], e.person_templates
  527 + assert_equivalent [p1,p3], e.person_templates
528 528 end
529 529  
530 530 should 'person_templates return an empty array if there is no templates of person' do
... ... @@ -532,7 +532,7 @@ class EnvironmentTest &lt; ActiveSupport::TestCase
532 532  
533 533 fast_create(Person, :environment_id => e.id)
534 534 fast_create(Person, :environment_id => e.id)
535   - assert_equivalent [], e.person_templates
  535 + assert_equivalent [], e.person_templates
536 536 end
537 537  
538 538 should 'person_default_template return the template defined as default' do
... ... @@ -585,7 +585,7 @@ class EnvironmentTest &lt; ActiveSupport::TestCase
585 585 c1= fast_create(Community, :is_template => true, :environment_id => e.id)
586 586 c2 = fast_create(Community, :environment_id => e.id)
587 587 c3 = fast_create(Community, :is_template => true, :environment_id => e.id)
588   - assert_equivalent [c1,c3], e.community_templates
  588 + assert_equivalent [c1,c3], e.community_templates
589 589 end
590 590  
591 591 should 'community_templates return an empty array if there is no templates of community' do
... ... @@ -646,7 +646,7 @@ class EnvironmentTest &lt; ActiveSupport::TestCase
646 646 e1= fast_create(Enterprise, :is_template => true, :environment_id => env.id)
647 647 e2 = fast_create(Enterprise, :environment_id => env.id)
648 648 e3 = fast_create(Enterprise, :is_template => true, :environment_id => env.id)
649   - assert_equivalent [e1,e3], env.enterprise_templates
  649 + assert_equivalent [e1,e3], env.enterprise_templates
650 650 end
651 651  
652 652 should 'enterprise_templates return an empty array if there is no templates of enterprise' do
... ... @@ -654,7 +654,7 @@ class EnvironmentTest &lt; ActiveSupport::TestCase
654 654  
655 655 fast_create(Enterprise, :environment_id => env.id)
656 656 fast_create(Enterprise, :environment_id => env.id)
657   - assert_equivalent [], env.enterprise_templates
  657 + assert_equivalent [], env.enterprise_templates
658 658 end
659 659  
660 660 should 'enterprise_default_template return the template defined as default' do
... ... @@ -1428,6 +1428,36 @@ class EnvironmentTest &lt; ActiveSupport::TestCase
1428 1428 assert !environment.plugin_enabled?(Plugin)
1429 1429 end
1430 1430  
  1431 + should 'activate on database all available plugins' do
  1432 + plugins_enable = ["Statistics", "Foo", "PeopleBlock"]
  1433 + Noosfero::Plugins.stubs(:available_plugin_names).returns(plugins_enable)
  1434 + env1 = Environment.create(:name => "Test")
  1435 + env2 = Environment.create(:name => "Test 2")
  1436 +
  1437 + env1.enable_all_plugins
  1438 + env2.enable_all_plugins
  1439 +
  1440 + plugins = ["PeopleBlockPlugin", "StatisticsPlugin", "FooPlugin"]
  1441 + plugins.each do |plugin|
  1442 + assert env1.enabled_plugins.include?(plugin)
  1443 + assert env2.enabled_plugins.include?(plugin)
  1444 + end
  1445 + end
  1446 +
  1447 + should 'dont activate plugins that are not available' do
  1448 + env1 = Environment.create(:name => "Test")
  1449 + env2 = Environment.create(:name => "Test 2")
  1450 +
  1451 + env1.enable_all_plugins
  1452 + env2.enable_all_plugins
  1453 +
  1454 + plugins = ["SomePlugin", "OtherPlugin", "ThirdPlugin"]
  1455 + plugins.each do |plugin|
  1456 + assert_equal false, env1.enabled_plugins.include?(plugin)
  1457 + assert_equal false, env2.enabled_plugins.include?(plugin)
  1458 + end
  1459 + end
  1460 +
1431 1461 should 'have production costs' do
1432 1462 assert_respond_to Environment.default, :production_costs
1433 1463 end
... ...
test/unit/folder_helper_test.rb
... ... @@ -68,7 +68,7 @@ class FolderHelperTest &lt; ActionView::TestCase
68 68 profile.public_profile = false
69 69 profile.save!
70 70 profile2 = create_user('Folder Viwer').person
71   - folder = fast_create(Folder, :profile_id => profile.id)
  71 + folder = fast_create(Folder, :profile_id => profile.id, :published => false)
72 72 article = fast_create(Article, {:parent_id => folder.id, :profile_id => profile.id})
73 73  
74 74 result = available_articles(folder.children, profile2)
... ...
test/unit/forum_test.rb
... ... @@ -174,4 +174,70 @@ class ForumTest &lt; ActiveSupport::TestCase
174 174 assert_equal true, Forum.find(forum.id).agrees_with_terms?(person)
175 175 end
176 176  
  177 + should 'always allow topic creation to the person himself' do
  178 + person = fast_create(Person)
  179 + someone = fast_create(Person)
  180 + forum = Forum.new(:profile => person)
  181 +
  182 + assert forum.can_create_topic?(person)
  183 + assert !forum.can_create_topic?(someone)
  184 + end
  185 +
  186 + should 'always allow topic creation to profile admins' do
  187 + admin = fast_create(Person)
  188 + someone = fast_create(Person)
  189 + profile = fast_create(Profile)
  190 + admins = [admin]
  191 + profile.stubs(:admins).returns(admins)
  192 + forum = Forum.new(:profile => profile)
  193 +
  194 + assert forum.can_create_topic?(admin)
  195 + assert !forum.can_create_topic?(someone)
  196 + end
  197 +
  198 + should 'always allow topic creation to environment admins' do
  199 + admin = fast_create(Person)
  200 + someone = fast_create(Person)
  201 + profile = fast_create(Profile)
  202 + admins = [admin]
  203 + environment = profile.environment
  204 + environment.stubs(:admins).returns(admins)
  205 + forum = Forum.new(:profile => profile)
  206 +
  207 + assert forum.can_create_topic?(admin)
  208 + assert !forum.can_create_topic?(someone)
  209 + end
  210 +
  211 + should 'allow only person friends to create topics when topic_creation is related' do
  212 + person = fast_create(Person)
  213 + friend = fast_create(Person)
  214 + someone = fast_create(Person)
  215 + friends = [friend]
  216 + person.stubs(:friends).returns(friends)
  217 + forum = Forum.new(:profile => person, :topic_creation => 'related')
  218 +
  219 + assert forum.can_create_topic?(friend)
  220 + assert !forum.can_create_topic?(someone)
  221 + end
  222 +
  223 + should 'allow only group members to create topics when topic_creation is related' do
  224 + organization = fast_create(Organization)
  225 + member = fast_create(Person)
  226 + someone = fast_create(Person)
  227 + members = [member]
  228 + organization.stubs(:members).returns(members)
  229 + forum = Forum.new(:profile => organization, :topic_creation => 'related')
  230 +
  231 + assert forum.can_create_topic?(member)
  232 + assert !forum.can_create_topic?(someone)
  233 + end
  234 +
  235 + should 'allow every user to create topics when topic_creation is users' do
  236 + profile = fast_create(Profile)
  237 + user = fast_create(Person)
  238 + forum = Forum.new(:profile => profile, :topic_creation => 'users')
  239 +
  240 + assert forum.can_create_topic?(user)
  241 + assert !forum.can_create_topic?(nil)
  242 + end
177 243 end
... ...
test/unit/profile_test.rb
... ... @@ -1122,6 +1122,23 @@ class ProfileTest &lt; ActiveSupport::TestCase
1122 1122 assert_equal 'default title', p.boxes[0].blocks.first[:title]
1123 1123 end
1124 1124  
  1125 + should 'have blocks observer on template when applying template with mirror' do
  1126 + template = fast_create(Profile)
  1127 + template.boxes.destroy_all
  1128 + template.boxes << Box.new
  1129 + b = Block.new(:title => 'default title', :mirror => true)
  1130 + template.boxes[0].blocks << b
  1131 +
  1132 + p = create(Profile)
  1133 + assert !b[:title].blank?
  1134 +
  1135 + p.copy_blocks_from(template)
  1136 +
  1137 + assert_equal 'default title', p.boxes[0].blocks.first[:title]
  1138 + assert_equal p.boxes[0].blocks.first, template.boxes[0].blocks.first.observers.first
  1139 +
  1140 + end
  1141 +
1125 1142 TMP_THEMES_DIR = Rails.root.join('test', 'tmp', 'profile_themes')
1126 1143 should 'have themes' do
1127 1144 Theme.stubs(:user_themes_dir).returns(TMP_THEMES_DIR)
... ...
test/unit/task_mailer_test.rb
... ... @@ -119,7 +119,7 @@ class TaskMailerTest &lt; ActiveSupport::TestCase
119 119 assert_match(/#{task.target_notification_description}/, mail.subject)
120 120  
121 121 assert_equal "Hello friend name, my name invite you, please follow this link: http://example.com/account/signup?invitation_code=123456", mail.body.to_s
122   -
  122 +
123 123 mail.deliver
124 124 assert !ActionMailer::Base.deliveries.empty?
125 125 end
... ... @@ -135,6 +135,36 @@ class TaskMailerTest &lt; ActiveSupport::TestCase
135 135 assert_equal 'My name <email@example.com>', TaskMailer.generate_from(task)
136 136 end
137 137  
  138 + should 'return the email with the subdirectory defined' do
  139 + Noosfero.stubs(:root).returns('/subdir')
  140 +
  141 + task = InviteFriend.new
  142 + task.expects(:code).returns('123456')
  143 +
  144 + task.stubs(:message).returns('Hello <friend>, <user> invite you, please follow this link: <url>')
  145 + task.expects(:friend_email).returns('friend@exemple.com')
  146 + task.expects(:friend_name).returns('friend name').at_least_once
  147 +
  148 + requestor = mock()
  149 + requestor.stubs(:name).returns('my name')
  150 + requestor.stubs(:public_profile_url).returns('requestor_path')
  151 +
  152 + environment = mock()
  153 + environment.expects(:noreply_email).returns('sender@example.com')
  154 + environment.expects(:default_hostname).returns('example.com')
  155 + environment.expects(:name).returns('example').at_least_once
  156 +
  157 + task.expects(:requestor).returns(requestor).at_least_once
  158 + task.expects(:person).returns(requestor).at_least_once
  159 + requestor.expects(:environment).returns(environment).at_least_once
  160 + task.expects(:environment).returns(environment).at_least_once
  161 +
  162 + mail = TaskMailer.invitation_notification(task)
  163 +
  164 + url_to_compare = "/subdir/account/signup"
  165 +
  166 + assert_match(/#{url_to_compare}/, mail.body.to_s)
  167 + end
138 168  
139 169 private
140 170 def read_fixture(action)
... ...
util/chat/apache/xmpp.conf
1 1 # If your XMPP XMPP/BOSH isn't in localhost, change the config below to correct
2 2 # point to address
3 3  
  4 + RewriteEngine On
4 5 RewriteRule /http-bind http://localhost:5280/http-bind [P,QSA,L]
5 6 <Proxy http://localhost:5280/http-bind>
6 7 Order Allow,Deny
... ...