Commit fa46a8f5fc858a9410e0f3b20753f5ea9e9710f2
Exists in
oauth_external_login
and in
1 other branch
Merge branch 'external-person' into 'federation'
External person Allow external users to login in a network that is federated with the user's network. See merge request !951
Showing
53 changed files
with
1289 additions
and
275 deletions
Show diff stats
app/api/app.rb
1 | require_dependency 'api/helpers' | 1 | require_dependency 'api/helpers' |
2 | 2 | ||
3 | module Api | 3 | module Api |
4 | + class NoosferoFederation < Grape::API | ||
5 | + use Rack::JSONP | ||
6 | + helpers Helpers | ||
7 | + before { detect_stuff_by_domain } | ||
8 | + format :json | ||
9 | + content_type :json, "application/jrd+json" | ||
10 | + prefix [ENV['RAILS_RELATIVE_URL_ROOT'], ".well-known"].compact.join('/') | ||
11 | + mount Federation::Webfinger | ||
12 | + end | ||
13 | + | ||
4 | class App < Grape::API | 14 | class App < Grape::API |
5 | use Rack::JSONP | 15 | use Rack::JSONP |
6 | 16 | ||
@@ -23,6 +33,8 @@ module Api | @@ -23,6 +33,8 @@ module Api | ||
23 | end | 33 | end |
24 | end | 34 | end |
25 | 35 | ||
36 | + mount NoosferoFederation | ||
37 | + | ||
26 | before { set_locale } | 38 | before { set_locale } |
27 | before { setup_multitenancy } | 39 | before { setup_multitenancy } |
28 | before { detect_stuff_by_domain } | 40 | before { detect_stuff_by_domain } |
@@ -0,0 +1,108 @@ | @@ -0,0 +1,108 @@ | ||
1 | +require 'rails/commands/server' | ||
2 | + | ||
3 | +module Api | ||
4 | + module Federation | ||
5 | + class Webfinger < Grape::API | ||
6 | + get 'webfinger' do | ||
7 | + result = generate_jrd | ||
8 | + present result, with: Grape::Presenters::Presenter | ||
9 | + end | ||
10 | + end | ||
11 | + end | ||
12 | +end | ||
13 | + | ||
14 | +def generate_jrd | ||
15 | + unless valid_domain? | ||
16 | + not_found! | ||
17 | + Rails.logger.error 'Domain Not Found' | ||
18 | + end | ||
19 | + if request_acct? | ||
20 | + acct_hash | ||
21 | + elsif valid_uri?(params[:resource]) | ||
22 | + uri_hash | ||
23 | + end | ||
24 | +end | ||
25 | + | ||
26 | +def domain | ||
27 | + if request_acct? | ||
28 | + params[:resource].split('@')[1] | ||
29 | + else | ||
30 | + params[:resource].split('/')[2] | ||
31 | + end | ||
32 | +end | ||
33 | + | ||
34 | +def valid_domain? | ||
35 | + environment.domains.map(&:name).include? domain | ||
36 | +end | ||
37 | + | ||
38 | +def request_acct? | ||
39 | + params[:resource].include? 'acct:' | ||
40 | +end | ||
41 | + | ||
42 | +def acct_hash | ||
43 | + rails = Rails::Server.new | ||
44 | + acct = Hash.new{|hash, key| hash[key] = Hash.new{|hash, key| hash[key] = Array.new}} | ||
45 | + url = rails.options[:Host] + ':' + rails.options[:Port].to_s + '/' | ||
46 | + person = Person.find_by_identifier(extract_person_identifier) | ||
47 | + | ||
48 | + if person.nil? | ||
49 | + Rails.logger.error 'Person not found' | ||
50 | + not_found! | ||
51 | + else | ||
52 | + acct[:subject] = params[:resource] | ||
53 | + acct[:alias] = url + person.identifier | ||
54 | + acct[:properties][:identifier] = person.identifier | ||
55 | + acct[:properties][:created_at] = person.created_at | ||
56 | + for blog in person.blogs do | ||
57 | + acct[:links][:rel] << url + 'rel/' + blog.path | ||
58 | + acct[:links][:href] << url + person.identifier + '/' + blog.path | ||
59 | + end | ||
60 | + | ||
61 | + for galleries in person.articles.galleries do | ||
62 | + acct[:links][:rel] << url + 'rel/' + galleries.path | ||
63 | + acct[:links][:href] << url + person.identifier + '/' + galleries.path | ||
64 | + end | ||
65 | + | ||
66 | + acct[:titles][:name] = person.name | ||
67 | + end | ||
68 | + acct | ||
69 | +end | ||
70 | + | ||
71 | +def extract_person_identifier | ||
72 | + params[:resource].split('@')[0].split(':')[1] | ||
73 | +end | ||
74 | + | ||
75 | +def valid_uri?(url) | ||
76 | + uri = URI.parse(url) | ||
77 | + if uri.is_a?(URI::HTTP) | ||
78 | + true | ||
79 | + else | ||
80 | + Rails.logger.error 'Bad URI Error' | ||
81 | + not_found! | ||
82 | + end | ||
83 | +end | ||
84 | + | ||
85 | +def uri_hash | ||
86 | + uri = {} | ||
87 | + uri[:subject] = params[:resource] | ||
88 | + entity = find_entity(params[:resource]) | ||
89 | + id = params[:resource].split('/').last.to_i | ||
90 | + begin | ||
91 | + uri[:properties] = entity.classify.constantize.find(id) | ||
92 | + rescue ActiveRecord::RecordNotFound | ||
93 | + Rails.logger.error "Entity: #{entity} with id: #{id} not found" | ||
94 | + not_found! | ||
95 | + end | ||
96 | + uri | ||
97 | +end | ||
98 | + | ||
99 | +def find_entity(uri) | ||
100 | + possible_entity = uri.split('/') | ||
101 | + possible_entity.map! { |entity| "#{entity}s" } | ||
102 | + entity = (ActiveRecord::Base.connection.tables & possible_entity).first | ||
103 | + unless entity | ||
104 | + Rails.logger.error 'Entity not found on records' | ||
105 | + not_found! | ||
106 | + end | ||
107 | + entity | ||
108 | +end |
app/api/helpers.rb
@@ -10,6 +10,9 @@ module Api | @@ -10,6 +10,9 @@ module Api | ||
10 | include Noosfero::Plugin::HotSpot | 10 | include Noosfero::Plugin::HotSpot |
11 | include ForgotPasswordHelper | 11 | include ForgotPasswordHelper |
12 | include SearchTermHelper | 12 | include SearchTermHelper |
13 | + include ProfileImageHelper | ||
14 | + include Noosfero::Gravatar | ||
15 | + include ThemeLoaderHelper | ||
13 | 16 | ||
14 | def set_locale | 17 | def set_locale |
15 | I18n.locale = (params[:lang] || request.env['HTTP_ACCEPT_LANGUAGE'] || 'en') | 18 | I18n.locale = (params[:lang] || request.env['HTTP_ACCEPT_LANGUAGE'] || 'en') |
@@ -412,7 +415,7 @@ module Api | @@ -412,7 +415,7 @@ module Api | ||
412 | content_type == 'TextArticle' ? Article.text_article_types : content_type | 415 | content_type == 'TextArticle' ? Article.text_article_types : content_type |
413 | end | 416 | end |
414 | content_types.flatten.uniq | 417 | content_types.flatten.uniq |
415 | - end | 418 | + end |
416 | 419 | ||
417 | def period(from_date, until_date) | 420 | def period(from_date, until_date) |
418 | begin_period = from_date.nil? ? Time.at(0).to_datetime : from_date | 421 | begin_period = from_date.nil? ? Time.at(0).to_datetime : from_date |
app/api/v1/articles.rb
@@ -62,7 +62,7 @@ module Api | @@ -62,7 +62,7 @@ module Api | ||
62 | { :success => true } | 62 | { :success => true } |
63 | rescue Exception => exception | 63 | rescue Exception => exception |
64 | render_api_error!(_('The article couldn\'t be removed due to some problem. Please contact the administrator.'), 400) | 64 | render_api_error!(_('The article couldn\'t be removed due to some problem. Please contact the administrator.'), 400) |
65 | - end | 65 | + end |
66 | end | 66 | end |
67 | 67 | ||
68 | desc 'Report a abuse and/or violent content in a article by id' do | 68 | desc 'Report a abuse and/or violent content in a article by id' do |
app/api/v1/people.rb
@@ -108,6 +108,23 @@ module Api | @@ -108,6 +108,23 @@ module Api | ||
108 | end | 108 | end |
109 | present output | 109 | present output |
110 | end | 110 | end |
111 | + | ||
112 | + desc "Return the person profile picture (you can optionally pass a 'size' parameter)" | ||
113 | + get ":id/icon" do | ||
114 | + person = environment.people.find(params[:id]) | ||
115 | + | ||
116 | + size = params[:size] || :portrait | ||
117 | + image = profile_icon(person, size.to_sym) | ||
118 | + output = {} | ||
119 | + | ||
120 | + unless image.match(/^\/\/www\.gravatar\.com/).nil? | ||
121 | + output[:icon] = 'https:' + image | ||
122 | + else | ||
123 | + output[:icon] = request.url.gsub(/\/api\/.*/, '') + image | ||
124 | + end | ||
125 | + | ||
126 | + present output | ||
127 | + end | ||
111 | end | 128 | end |
112 | 129 | ||
113 | resource :profiles do | 130 | resource :profiles do |
app/concerns/authenticated_system.rb
@@ -25,7 +25,19 @@ module AuthenticatedSystem | @@ -25,7 +25,19 @@ module AuthenticatedSystem | ||
25 | # Accesses the current user from the session. | 25 | # Accesses the current user from the session. |
26 | def current_user user_id = session[:user] | 26 | def current_user user_id = session[:user] |
27 | @current_user ||= begin | 27 | @current_user ||= begin |
28 | - user = User.find_by id: user_id if user_id | 28 | + user = nil |
29 | + if session[:external] | ||
30 | + user = User.new | ||
31 | + external_person = ExternalPerson.find_by(id: session[:external]) | ||
32 | + if external_person | ||
33 | + user.external_person_id = external_person.id | ||
34 | + user.email = external_person.email | ||
35 | + else | ||
36 | + session[:external] = nil | ||
37 | + end | ||
38 | + else | ||
39 | + user = User.find_by(id: user_id) if user_id | ||
40 | + end | ||
29 | user.session = session if user | 41 | user.session = session if user |
30 | User.current = user | 42 | User.current = user |
31 | user | 43 | user |
@@ -37,9 +49,13 @@ module AuthenticatedSystem | @@ -37,9 +49,13 @@ module AuthenticatedSystem | ||
37 | if new_user.nil? | 49 | if new_user.nil? |
38 | session.delete(:user) | 50 | session.delete(:user) |
39 | else | 51 | else |
40 | - session[:user] = new_user.id | 52 | + if new_user.id |
53 | + session[:user] = new_user.id | ||
54 | + else | ||
55 | + session[:external] = new_user.external_person_id | ||
56 | + end | ||
41 | new_user.session = session | 57 | new_user.session = session |
42 | - new_user.register_login | 58 | + new_user.register_login if new_user.id |
43 | end | 59 | end |
44 | @current_user = User.current = new_user | 60 | @current_user = User.current = new_user |
45 | end | 61 | end |
app/controllers/application_controller.rb
@@ -8,6 +8,7 @@ class ApplicationController < ActionController::Base | @@ -8,6 +8,7 @@ class ApplicationController < ActionController::Base | ||
8 | before_filter :allow_cross_domain_access | 8 | before_filter :allow_cross_domain_access |
9 | 9 | ||
10 | include AuthenticatedSystem | 10 | include AuthenticatedSystem |
11 | + | ||
11 | before_filter :require_login_for_environment, :if => :private_environment? | 12 | before_filter :require_login_for_environment, :if => :private_environment? |
12 | 13 | ||
13 | before_filter :verify_members_whitelist, :if => [:private_environment?, :user] | 14 | before_filter :verify_members_whitelist, :if => [:private_environment?, :user] |
@@ -120,7 +121,9 @@ class ApplicationController < ActionController::Base | @@ -120,7 +121,9 @@ class ApplicationController < ActionController::Base | ||
120 | end | 121 | end |
121 | 122 | ||
122 | def user | 123 | def user |
123 | - current_user.person if logged_in? | 124 | + if logged_in? |
125 | + current_user.person || current_user.external_person | ||
126 | + end | ||
124 | end | 127 | end |
125 | 128 | ||
126 | alias :current_person :user | 129 | alias :current_person :user |
app/controllers/my_profile/email_templates_controller.rb
@@ -64,7 +64,7 @@ class EmailTemplatesController < ApplicationController | @@ -64,7 +64,7 @@ class EmailTemplatesController < ApplicationController | ||
64 | private | 64 | private |
65 | 65 | ||
66 | def template_params | 66 | def template_params |
67 | - {:profile_name => current_user.name, :environment_name => environment.name } | 67 | + {:profile_name => current_person.name, :environment_name => environment.name } |
68 | end | 68 | end |
69 | 69 | ||
70 | def template_params_allowed params | 70 | def template_params_allowed params |
app/controllers/public/profile_controller.rb
@@ -176,7 +176,7 @@ class ProfileController < PublicController | @@ -176,7 +176,7 @@ class ProfileController < PublicController | ||
176 | end | 176 | end |
177 | 177 | ||
178 | def unblock | 178 | def unblock |
179 | - if current_user.person.is_admin?(profile.environment) | 179 | + if current_person.is_admin?(profile.environment) |
180 | profile.unblock | 180 | profile.unblock |
181 | session[:notice] = _("You have unblocked %s successfully. ") % profile.name | 181 | session[:notice] = _("You have unblocked %s successfully. ") % profile.name |
182 | redirect_to :controller => 'profile', :action => 'index' | 182 | redirect_to :controller => 'profile', :action => 'index' |
@@ -187,7 +187,7 @@ class ProfileController < PublicController | @@ -187,7 +187,7 @@ class ProfileController < PublicController | ||
187 | end | 187 | end |
188 | 188 | ||
189 | def leave_scrap | 189 | def leave_scrap |
190 | - sender = params[:sender_id].nil? ? current_user.person : Person.find(params[:sender_id]) | 190 | + sender = params[:sender_id].nil? ? current_person : Person.find(params[:sender_id]) |
191 | receiver = params[:receiver_id].nil? ? @profile : Person.find(params[:receiver_id]) | 191 | receiver = params[:receiver_id].nil? ? @profile : Person.find(params[:receiver_id]) |
192 | @scrap = Scrap.new(params[:scrap]) | 192 | @scrap = Scrap.new(params[:scrap]) |
193 | @scrap.sender= sender | 193 | @scrap.sender= sender |
@@ -270,7 +270,7 @@ class ProfileController < PublicController | @@ -270,7 +270,7 @@ class ProfileController < PublicController | ||
270 | 270 | ||
271 | def remove_scrap | 271 | def remove_scrap |
272 | begin | 272 | begin |
273 | - scrap = current_user.person.scraps(params[:scrap_id]) | 273 | + scrap = current_person.scraps(params[:scrap_id]) |
274 | scrap.destroy | 274 | scrap.destroy |
275 | finish_successful_removal 'Scrap successfully removed.' | 275 | finish_successful_removal 'Scrap successfully removed.' |
276 | rescue | 276 | rescue |
@@ -395,6 +395,17 @@ class ProfileController < PublicController | @@ -395,6 +395,17 @@ class ProfileController < PublicController | ||
395 | end | 395 | end |
396 | end | 396 | end |
397 | 397 | ||
398 | + def icon | ||
399 | + size = params[:size] || :portrait | ||
400 | + image, mime = profile_icon(profile, size.to_sym, true) | ||
401 | + | ||
402 | + unless image.match(/^\/\/www\.gravatar\.com/).nil? | ||
403 | + redirect_to 'https:' + image | ||
404 | + else | ||
405 | + @file = File.join(Rails.root, 'public', image) | ||
406 | + send_file @file, type: mime, disposition: 'inline' | ||
407 | + end | ||
408 | + end | ||
398 | 409 | ||
399 | protected | 410 | protected |
400 | 411 |
app/controllers/public/search_controller.rb
@@ -247,7 +247,7 @@ class SearchController < PublicController | @@ -247,7 +247,7 @@ class SearchController < PublicController | ||
247 | def visible_profiles(klass, *extra_relations) | 247 | def visible_profiles(klass, *extra_relations) |
248 | relations = [:image, :domains, :environment, :preferred_domain] | 248 | relations = [:image, :domains, :environment, :preferred_domain] |
249 | relations += extra_relations | 249 | relations += extra_relations |
250 | - if current_user && current_user.person.is_admin? | 250 | + if current_user && current_person.is_admin? |
251 | @environment.send(klass.name.underscore.pluralize).includes(relations) | 251 | @environment.send(klass.name.underscore.pluralize).includes(relations) |
252 | else | 252 | else |
253 | @environment.send(klass.name.underscore.pluralize).visible.includes(relations) | 253 | @environment.send(klass.name.underscore.pluralize).visible.includes(relations) |
app/helpers/application_helper.rb
@@ -146,12 +146,12 @@ module ApplicationHelper | @@ -146,12 +146,12 @@ module ApplicationHelper | ||
146 | end | 146 | end |
147 | 147 | ||
148 | def link_to_cms(text, profile = nil, options = {}) | 148 | def link_to_cms(text, profile = nil, options = {}) |
149 | - profile ||= current_user.login | 149 | + profile ||= current_person.identifier |
150 | link_to text, myprofile_path(:controller => 'cms', :profile => profile), options | 150 | link_to text, myprofile_path(:controller => 'cms', :profile => profile), options |
151 | end | 151 | end |
152 | 152 | ||
153 | def link_to_profile(text, profile = nil, options = {}) | 153 | def link_to_profile(text, profile = nil, options = {}) |
154 | - profile ||= current_user.login | 154 | + profile ||= current_person.identifier |
155 | link_to text, profile_path(:profile => profile) , options | 155 | link_to text, profile_path(:profile => profile) , options |
156 | end | 156 | end |
157 | 157 | ||
@@ -160,7 +160,7 @@ module ApplicationHelper | @@ -160,7 +160,7 @@ module ApplicationHelper | ||
160 | end | 160 | end |
161 | 161 | ||
162 | def link_if_permitted(link, permission = nil, target = nil) | 162 | def link_if_permitted(link, permission = nil, target = nil) |
163 | - if permission.nil? || current_user.person.has_permission?(permission, target) | 163 | + if permission.nil? || current_person.has_permission?(permission, target) |
164 | link | 164 | link |
165 | else | 165 | else |
166 | nil | 166 | nil |
@@ -814,7 +814,7 @@ module ApplicationHelper | @@ -814,7 +814,7 @@ module ApplicationHelper | ||
814 | {s_('contents|Most commented') => {href: url_for({host: host, controller: 'search', action: 'contents', filter: 'more_comments'})}} | 814 | {s_('contents|Most commented') => {href: url_for({host: host, controller: 'search', action: 'contents', filter: 'more_comments'})}} |
815 | ] | 815 | ] |
816 | if logged_in? | 816 | if logged_in? |
817 | - links.push(_('New content') => modal_options({:href => url_for({:controller => 'cms', :action => 'new', :profile => current_user.login, :cms => true})})) | 817 | + links.push(_('New content') => modal_options({:href => url_for({:controller => 'cms', :action => 'new', :profile => current_person.identifier, :cms => true})})) |
818 | end | 818 | end |
819 | 819 | ||
820 | link_to(content_tag(:span, _('Contents'), :class => 'icon-menu-articles'), {:controller => "search", :action => 'contents', :category_path => nil}, :id => 'submenu-contents') + | 820 | link_to(content_tag(:span, _('Contents'), :class => 'icon-menu-articles'), {:controller => "search", :action => 'contents', :category_path => nil}, :id => 'submenu-contents') + |
@@ -830,8 +830,8 @@ module ApplicationHelper | @@ -830,8 +830,8 @@ module ApplicationHelper | ||
830 | {s_('people|More popular') => {href: url_for({host: host, controller: 'search', action: 'people', filter: 'more_popular'})}} | 830 | {s_('people|More popular') => {href: url_for({host: host, controller: 'search', action: 'people', filter: 'more_popular'})}} |
831 | ] | 831 | ] |
832 | if logged_in? | 832 | if logged_in? |
833 | - links.push(_('My friends') => {:href => url_for({:profile => current_user.login, :controller => 'friends'})}) | ||
834 | - links.push(_('Invite friends') => {:href => url_for({:profile => current_user.login, :controller => 'invite', :action => 'friends'})}) | 833 | + links.push(_('My friends') => {:href => url_for({:profile => current_person.identifier, :controller => 'friends'})}) |
834 | + links.push(_('Invite friends') => {:href => url_for({:profile => current_person.identifier, :controller => 'invite', :action => 'friends'})}) | ||
835 | end | 835 | end |
836 | 836 | ||
837 | link_to(content_tag(:span, _('People'), :class => 'icon-menu-people'), {:controller => "search", :action => 'people', :category_path => ''}, :id => 'submenu-people') + | 837 | link_to(content_tag(:span, _('People'), :class => 'icon-menu-people'), {:controller => "search", :action => 'people', :category_path => ''}, :id => 'submenu-people') + |
@@ -847,8 +847,8 @@ module ApplicationHelper | @@ -847,8 +847,8 @@ module ApplicationHelper | ||
847 | {s_('communities|More popular') => {href: url_for({host: host, controller: 'search', action: 'communities', filter: 'more_popular'})}} | 847 | {s_('communities|More popular') => {href: url_for({host: host, controller: 'search', action: 'communities', filter: 'more_popular'})}} |
848 | ] | 848 | ] |
849 | if logged_in? | 849 | if logged_in? |
850 | - links.push(_('My communities') => {:href => url_for({:profile => current_user.login, :controller => 'memberships'})}) | ||
851 | - links.push(_('New community') => {:href => url_for({:profile => current_user.login, :controller => 'memberships', :action => 'new_community'})}) | 850 | + links.push(_('My communities') => {:href => url_for({:profile => current_person.identifier, :controller => 'memberships'})}) |
851 | + links.push(_('New community') => {:href => url_for({:profile => current_person.identifier, :controller => 'memberships', :action => 'new_community'})}) | ||
852 | end | 852 | end |
853 | 853 | ||
854 | link_to(content_tag(:span, _('Communities'), :class => 'icon-menu-community'), {:controller => "search", :action => 'communities'}, :id => 'submenu-communities') + | 854 | link_to(content_tag(:span, _('Communities'), :class => 'icon-menu-community'), {:controller => "search", :action => 'communities'}, :id => 'submenu-communities') + |
app/helpers/theme_loader_helper.rb
@@ -2,7 +2,7 @@ module ThemeLoaderHelper | @@ -2,7 +2,7 @@ module ThemeLoaderHelper | ||
2 | def current_theme | 2 | def current_theme |
3 | @current_theme ||= | 3 | @current_theme ||= |
4 | begin | 4 | begin |
5 | - if session[:user_theme] | 5 | + if defined?(session).present? && session[:user_theme] |
6 | session[:user_theme] | 6 | session[:user_theme] |
7 | else | 7 | else |
8 | # utility for developers: set the theme to 'random' in development mode and | 8 | # utility for developers: set the theme to 'random' in development mode and |
@@ -14,7 +14,7 @@ module ThemeLoaderHelper | @@ -14,7 +14,7 @@ module ThemeLoaderHelper | ||
14 | elsif Rails.env.development? && respond_to?(:params) && params[:user_theme] && File.exists?(Rails.root.join('public/designs/themes', params[:user_theme])) | 14 | elsif Rails.env.development? && respond_to?(:params) && params[:user_theme] && File.exists?(Rails.root.join('public/designs/themes', params[:user_theme])) |
15 | params[:user_theme] | 15 | params[:user_theme] |
16 | else | 16 | else |
17 | - if profile && !profile.theme.nil? | 17 | + if defined?(profile) && profile && !profile.theme.nil? |
18 | profile.theme | 18 | profile.theme |
19 | elsif environment | 19 | elsif environment |
20 | environment.theme | 20 | environment.theme |
@@ -34,9 +34,9 @@ module ThemeLoaderHelper | @@ -34,9 +34,9 @@ module ThemeLoaderHelper | ||
34 | end | 34 | end |
35 | 35 | ||
36 | def theme_path | 36 | def theme_path |
37 | - if session[:user_theme] | 37 | + if defined?(session).present? && session[:user_theme] |
38 | '/user_themes/' + current_theme | 38 | '/user_themes/' + current_theme |
39 | - elsif session[:theme] | 39 | + elsif defined?(session).present? && session[:theme] |
40 | '/designs/themes/' + session[:theme] | 40 | '/designs/themes/' + session[:theme] |
41 | else | 41 | else |
42 | '/designs/themes/' + current_theme | 42 | '/designs/themes/' + current_theme |
app/models/abuse_complaint.rb
1 | class AbuseComplaint < Task | 1 | class AbuseComplaint < Task |
2 | has_many :abuse_reports, :dependent => :destroy | 2 | has_many :abuse_reports, :dependent => :destroy |
3 | - belongs_to :reported, :class_name => "Profile", :foreign_key => "requestor_id" | 3 | + belongs_to :reported, :polymorphic => true, :foreign_key => "requestor_id" |
4 | 4 | ||
5 | validates_presence_of :reported | 5 | validates_presence_of :reported |
6 | alias :requestor :reported | 6 | alias :requestor :reported |
app/models/abuse_report.rb
@@ -2,7 +2,7 @@ class AbuseReport < ApplicationRecord | @@ -2,7 +2,7 @@ class AbuseReport < ApplicationRecord | ||
2 | 2 | ||
3 | attr_accessible :content, :reason | 3 | attr_accessible :content, :reason |
4 | 4 | ||
5 | - belongs_to :reporter, :class_name => 'Person' | 5 | + belongs_to :reporter, :polymorphic => true |
6 | belongs_to :abuse_complaint | 6 | belongs_to :abuse_complaint |
7 | has_many :reported_images, :dependent => :destroy | 7 | has_many :reported_images, :dependent => :destroy |
8 | 8 |
app/models/comment.rb
@@ -15,7 +15,7 @@ class Comment < ApplicationRecord | @@ -15,7 +15,7 @@ class Comment < ApplicationRecord | ||
15 | alias :article= :source= | 15 | alias :article= :source= |
16 | attr_accessor :follow_article | 16 | attr_accessor :follow_article |
17 | 17 | ||
18 | - belongs_to :author, :class_name => 'Person', :foreign_key => 'author_id' | 18 | + belongs_to :author, :polymorphic => true, :foreign_key => 'author_id' |
19 | has_many :children, :class_name => 'Comment', :foreign_key => 'reply_of_id', :dependent => :destroy | 19 | has_many :children, :class_name => 'Comment', :foreign_key => 'reply_of_id', :dependent => :destroy |
20 | belongs_to :reply_of, :class_name => 'Comment', :foreign_key => 'reply_of_id' | 20 | belongs_to :reply_of, :class_name => 'Comment', :foreign_key => 'reply_of_id' |
21 | 21 |
@@ -0,0 +1,100 @@ | @@ -0,0 +1,100 @@ | ||
1 | +require 'ostruct' | ||
2 | + | ||
3 | +module ExternalUser | ||
4 | + extend ActiveSupport::Concern | ||
5 | + | ||
6 | + included do | ||
7 | + attr_accessor :external_person_id | ||
8 | + end | ||
9 | + | ||
10 | + def external_person | ||
11 | + ExternalPerson.where(id: self.external_person_id).first | ||
12 | + end | ||
13 | + | ||
14 | + def person_with_external | ||
15 | + self.external_person || self.person_without_external | ||
16 | + end | ||
17 | + | ||
18 | + module ClassMethods | ||
19 | + def webfinger_lookup(login, domain, environment) | ||
20 | + if login && domain && environment.has_federated_network?(domain) | ||
21 | + external_environment = environment.external_environments.find_by_url(domain) | ||
22 | + scheme = "http#{external_environment.uses_ssl? ? 's' : ''}" | ||
23 | + url = URI.parse(scheme+"://"+ domain +'/.well-known/webfinger?resource=acct:'+ | ||
24 | + login+'@'+domain) | ||
25 | + http = build_request(url) | ||
26 | + req = Net::HTTP::Get.new(url.to_s) | ||
27 | + res = http.request(req) | ||
28 | + JSON.parse(res.body) | ||
29 | + else | ||
30 | + nil | ||
31 | + end | ||
32 | + end | ||
33 | + | ||
34 | + def build_request(uri) | ||
35 | + request = Net::HTTP.new(uri.host, uri.port) | ||
36 | + if uri.scheme == "https" # enable SSL/TLS | ||
37 | + request.use_ssl = true | ||
38 | + #TODO There may be self-signed certificates that we would not be able | ||
39 | + #to verify, so we'll not verify the ssl certificate for now. Since | ||
40 | + #this requests will go only towards trusted federated networks the admin | ||
41 | + #configured we consider this not to be a big deal. Nonetheless we may be | ||
42 | + #able in the future to require/provide the CA Files on the federation | ||
43 | + #process which would allow us to verify the certificate. | ||
44 | + request.verify_mode = OpenSSL::SSL::VERIFY_NONE | ||
45 | + end | ||
46 | + request | ||
47 | + end | ||
48 | + | ||
49 | + def external_login(login, password, domain) | ||
50 | + # Call Noosfero /api/login | ||
51 | + result = nil | ||
52 | + response = nil | ||
53 | + redirections_allowed = 3 | ||
54 | + external_environment = ExternalEnvironment.find_by_url(domain) | ||
55 | + scheme = "http#{external_environment.uses_ssl? ? 's' : ''}" | ||
56 | + location = scheme + '://' + domain + '/api/v1/login' | ||
57 | + request_params = CGI.unescape({ login: login, password: password }.to_query) | ||
58 | + begin | ||
59 | + while redirections_allowed > 0 && (response.blank? || response.code == '301') | ||
60 | + uri = URI.parse(location) | ||
61 | + request = build_request(uri) | ||
62 | + response = request.post(uri.to_s, request_params) | ||
63 | + location = response.header['location'] | ||
64 | + redirections_allowed -= 1 | ||
65 | + end | ||
66 | + result = response.code.to_i / 100 === 2 ? JSON.parse(response.body) : nil | ||
67 | + rescue | ||
68 | + # Could not make request | ||
69 | + end | ||
70 | + result | ||
71 | + end | ||
72 | + | ||
73 | + # Authenticates a user from an external social network | ||
74 | + def external_authenticate(username, password, environment) | ||
75 | + if username && username.include?('@') | ||
76 | + login, domain = username.split('@') | ||
77 | + webfinger = User.webfinger_lookup(login, domain, environment) | ||
78 | + if webfinger | ||
79 | + user = User.external_login(login, password, domain) | ||
80 | + if user | ||
81 | + u = User.new | ||
82 | + u.email = user['user']['email'] | ||
83 | + u.login = login | ||
84 | + webfinger = OpenStruct.new( | ||
85 | + identifier: webfinger['properties']['identifier'], | ||
86 | + name: webfinger['titles']['name'], | ||
87 | + created_at: webfinger['properties']['created_at'], | ||
88 | + domain: domain, | ||
89 | + email: user['user']['email'] | ||
90 | + ) | ||
91 | + u.external_person_id = ExternalPerson.get_or_create(webfinger).id | ||
92 | + return u | ||
93 | + end | ||
94 | + end | ||
95 | + end | ||
96 | + nil | ||
97 | + end | ||
98 | + | ||
99 | + end | ||
100 | +end |
@@ -0,0 +1,42 @@ | @@ -0,0 +1,42 @@ | ||
1 | +module Human | ||
2 | + extend ActiveSupport::Concern | ||
3 | + | ||
4 | + included do | ||
5 | + has_many :comments, :as => :author, :foreign_key => :author_id | ||
6 | + has_many :abuse_reports, :as => :reporter, :foreign_key => 'reporter_id', :dependent => :destroy | ||
7 | + | ||
8 | + scope :abusers, -> { | ||
9 | + joins(:abuse_complaints).where('tasks.status = 3').distinct.select("#{self.table_name}.*") | ||
10 | + } | ||
11 | + scope :non_abusers, -> { | ||
12 | + distinct.select("#{self.table_name}.*"). | ||
13 | + joins("LEFT JOIN tasks ON #{self.table_name}.id = tasks.requestor_id AND tasks.type='AbuseComplaint'"). | ||
14 | + where("tasks.status != 3 OR tasks.id is NULL") | ||
15 | + } | ||
16 | + end | ||
17 | + | ||
18 | + def already_reported?(profile) | ||
19 | + abuse_reports.any? { |report| report.abuse_complaint.reported == profile && report.abuse_complaint.opened? } | ||
20 | + end | ||
21 | + | ||
22 | + def register_report(abuse_report, profile) | ||
23 | + AbuseComplaint.create!(:reported => profile, :target => profile.environment) if !profile.opened_abuse_complaint | ||
24 | + abuse_report.abuse_complaint = profile.opened_abuse_complaint | ||
25 | + abuse_report.reporter = self | ||
26 | + abuse_report.save! | ||
27 | + end | ||
28 | + | ||
29 | + def abuser? | ||
30 | + AbuseComplaint.finished.where(:requestor_id => self).count > 0 | ||
31 | + end | ||
32 | + | ||
33 | + # Sets the identifier for this person. Raises an exception when called on a | ||
34 | + # existing person (since peoples' identifiers cannot be changed) | ||
35 | + def identifier=(value) | ||
36 | + unless self.new_record? | ||
37 | + raise ArgumentError.new(_('An existing person cannot be renamed.')) | ||
38 | + end | ||
39 | + self[:identifier] = value | ||
40 | + end | ||
41 | + | ||
42 | +end |
@@ -0,0 +1,155 @@ | @@ -0,0 +1,155 @@ | ||
1 | +module ProfileEntity | ||
2 | + extend ActiveSupport::Concern | ||
3 | + | ||
4 | + included do | ||
5 | + attr_accessible :name, :identifier, :environment | ||
6 | + | ||
7 | + validates_presence_of :identifier, :name | ||
8 | + | ||
9 | + belongs_to :environment | ||
10 | + has_many :search_terms, :as => :context | ||
11 | + has_many :abuse_complaints, :as => :reported, :foreign_key => 'requestor_id', :dependent => :destroy | ||
12 | + | ||
13 | + before_create :set_default_environment | ||
14 | + | ||
15 | + scope :recent, -> limit=nil { order('id DESC').limit(limit) } | ||
16 | + | ||
17 | + end | ||
18 | + | ||
19 | + def disable | ||
20 | + self.visible = false | ||
21 | + self.save | ||
22 | + end | ||
23 | + | ||
24 | + def enable | ||
25 | + self.visible = true | ||
26 | + self.save | ||
27 | + end | ||
28 | + | ||
29 | + def opened_abuse_complaint | ||
30 | + abuse_complaints.opened.first | ||
31 | + end | ||
32 | + | ||
33 | + def set_default_environment | ||
34 | + if self.environment.nil? | ||
35 | + self.environment = Environment.default | ||
36 | + end | ||
37 | + true | ||
38 | + end | ||
39 | + | ||
40 | + # returns +false+ | ||
41 | + def person? | ||
42 | + self.kind_of?(Person) | ||
43 | + end | ||
44 | + | ||
45 | + def enterprise? | ||
46 | + self.kind_of?(Enterprise) | ||
47 | + end | ||
48 | + | ||
49 | + def organization? | ||
50 | + self.kind_of?(Organization) | ||
51 | + end | ||
52 | + | ||
53 | + def community? | ||
54 | + self.kind_of?(Community) | ||
55 | + end | ||
56 | + | ||
57 | + include ActionView::Helpers::TextHelper | ||
58 | + def short_name(chars = 40) | ||
59 | + if self[:nickname].blank? | ||
60 | + if chars | ||
61 | + truncate self.name, length: chars, omission: '...' | ||
62 | + else | ||
63 | + self.name | ||
64 | + end | ||
65 | + else | ||
66 | + self[:nickname] | ||
67 | + end | ||
68 | + end | ||
69 | + | ||
70 | + def to_liquid | ||
71 | + HashWithIndifferentAccess.new :name => name, :identifier => identifier | ||
72 | + end | ||
73 | + | ||
74 | + # Tells whether a specified profile has members or nor. | ||
75 | + # | ||
76 | + # On this class, returns <tt>false</tt> by default. | ||
77 | + def has_members? | ||
78 | + false | ||
79 | + end | ||
80 | + | ||
81 | + def apply_type_specific_template(template) | ||
82 | + end | ||
83 | + | ||
84 | + # Override this method in subclasses of Profile to create a default article | ||
85 | + # set upon creation. Note that this method will be called *only* if there is | ||
86 | + # no template for the type of profile (i.e. if the template was removed or in | ||
87 | + # the creation of the template itself). | ||
88 | + # | ||
89 | + # This method must return an array of pre-populated articles, which will be | ||
90 | + # associated to the profile before being saved. Example: | ||
91 | + # | ||
92 | + # def default_set_of_articles | ||
93 | + # [Blog.new(:name => 'Blog'), Gallery.new(:name => 'Gallery')] | ||
94 | + # end | ||
95 | + # | ||
96 | + # By default, this method returns an empty array. | ||
97 | + def default_set_of_articles | ||
98 | + [] | ||
99 | + end | ||
100 | + | ||
101 | + def blocks_to_expire_cache | ||
102 | + [] | ||
103 | + end | ||
104 | + | ||
105 | + def cache_keys(params = {}) | ||
106 | + [] | ||
107 | + end | ||
108 | + | ||
109 | + def members_cache_key(params = {}) | ||
110 | + page = params[:npage] || '1' | ||
111 | + sort = (params[:sort] == 'desc') ? params[:sort] : 'asc' | ||
112 | + cache_key + '-members-page-' + page + '-' + sort | ||
113 | + end | ||
114 | + | ||
115 | + def more_recent_label | ||
116 | + _("Since: ") | ||
117 | + end | ||
118 | + | ||
119 | + def control_panel_settings_button | ||
120 | + {:title => _('Edit Profile'), :icon => 'edit-profile'} | ||
121 | + end | ||
122 | + | ||
123 | + def control_panel_settings_button | ||
124 | + {:title => _('Profile Info and settings'), :icon => 'edit-profile'} | ||
125 | + end | ||
126 | + | ||
127 | + def exclude_verbs_on_activities | ||
128 | + %w[] | ||
129 | + end | ||
130 | + | ||
131 | + def allow_invitation_from(person) | ||
132 | + false | ||
133 | + end | ||
134 | + | ||
135 | + def allow_post_content?(person = nil) | ||
136 | + person.kind_of?(Profile) && person.has_permission?('post_content', self) | ||
137 | + end | ||
138 | + | ||
139 | + def allow_edit?(person = nil) | ||
140 | + person.kind_of?(Profile) && person.has_permission?('edit_profile', self) | ||
141 | + end | ||
142 | + | ||
143 | + def allow_destroy?(person = nil) | ||
144 | + person.kind_of?(Profile) && person.has_permission?('destroy_profile', self) | ||
145 | + end | ||
146 | + | ||
147 | + module ClassMethods | ||
148 | + | ||
149 | + def identification | ||
150 | + name | ||
151 | + end | ||
152 | + | ||
153 | + end | ||
154 | + | ||
155 | +end |
app/models/environment.rb
@@ -1009,6 +1009,10 @@ class Environment < ApplicationRecord | @@ -1009,6 +1009,10 @@ class Environment < ApplicationRecord | ||
1009 | HashWithIndifferentAccess.new :name => name | 1009 | HashWithIndifferentAccess.new :name => name |
1010 | end | 1010 | end |
1011 | 1011 | ||
1012 | + def has_federated_network?(domain) | ||
1013 | + self.external_environments.map(&:url).any? { |url| /http[s]?:\/\/#{domain}\/?/ =~ url } | ||
1014 | + end | ||
1015 | + | ||
1012 | private | 1016 | private |
1013 | 1017 | ||
1014 | def default_language_available | 1018 | def default_language_available |
app/models/external_environment.rb
@@ -6,4 +6,9 @@ class ExternalEnvironment < ActiveRecord::Base | @@ -6,4 +6,9 @@ class ExternalEnvironment < ActiveRecord::Base | ||
6 | 6 | ||
7 | has_many :environment_external_environments, dependent: :destroy | 7 | has_many :environment_external_environments, dependent: :destroy |
8 | has_many :environments, through: :environment_external_environments | 8 | has_many :environments, through: :environment_external_environments |
9 | + | ||
10 | + def uses_ssl? | ||
11 | + url.starts_with? 'https' | ||
12 | + end | ||
13 | + | ||
9 | end | 14 | end |
@@ -0,0 +1,290 @@ | @@ -0,0 +1,290 @@ | ||
1 | +# A pseudo profile is a person from a remote network | ||
2 | +class ExternalPerson < ActiveRecord::Base | ||
3 | + | ||
4 | + include Human | ||
5 | + include ProfileEntity | ||
6 | + | ||
7 | + validates_uniqueness_of :identifier, scope: :source | ||
8 | + | ||
9 | + validates_presence_of :source, :email, :created_at | ||
10 | + | ||
11 | + attr_accessible :source, :email, :created_at | ||
12 | + | ||
13 | + def self.get_or_create(webfinger) | ||
14 | + user = ExternalPerson.find_by(identifier: webfinger.identifier, source: webfinger.domain) | ||
15 | + if user.nil? | ||
16 | + user = ExternalPerson.create!(identifier: webfinger.identifier, | ||
17 | + name: webfinger.name, | ||
18 | + source: webfinger.domain, | ||
19 | + email: webfinger.email, | ||
20 | + created_at: webfinger.created_at | ||
21 | + ) | ||
22 | + end | ||
23 | + user | ||
24 | + end | ||
25 | + | ||
26 | + def privacy_setting | ||
27 | + _('Public profile') | ||
28 | + end | ||
29 | + | ||
30 | + def avatar | ||
31 | + "http://#{self.source}/profile/#{self.identifier}/icon/" | ||
32 | + end | ||
33 | + | ||
34 | + def url | ||
35 | + "http://#{self.source}/profile/#{self.identifier}" | ||
36 | + end | ||
37 | + | ||
38 | + alias :public_profile_url :url | ||
39 | + | ||
40 | + def admin_url | ||
41 | + "http://#{self.source}/myprofile/#{self.identifier}" | ||
42 | + end | ||
43 | + | ||
44 | + def wall_url | ||
45 | + self.url | ||
46 | + end | ||
47 | + def tasks_url | ||
48 | + self.url | ||
49 | + end | ||
50 | + def leave_url(reload = false) | ||
51 | + self.url | ||
52 | + end | ||
53 | + def join_url | ||
54 | + self.url | ||
55 | + end | ||
56 | + def join_not_logged_url | ||
57 | + self.url | ||
58 | + end | ||
59 | + def check_membership_url | ||
60 | + self.url | ||
61 | + end | ||
62 | + def add_url | ||
63 | + self.url | ||
64 | + end | ||
65 | + def check_friendship_url | ||
66 | + self.url | ||
67 | + end | ||
68 | + def people_suggestions_url | ||
69 | + self.url | ||
70 | + end | ||
71 | + def communities_suggestions_url | ||
72 | + self.url | ||
73 | + end | ||
74 | + def top_url(scheme = 'http') | ||
75 | + "#{scheme}://#{self.source}" | ||
76 | + end | ||
77 | + | ||
78 | + def profile_custom_icon(gravatar_default=nil) | ||
79 | + self.avatar | ||
80 | + end | ||
81 | + | ||
82 | + def preferred_login_redirection | ||
83 | + environment.redirection_after_login | ||
84 | + end | ||
85 | + | ||
86 | + def location | ||
87 | + self.source | ||
88 | + end | ||
89 | + | ||
90 | + def default_hostname | ||
91 | + environment.default_hostname | ||
92 | + end | ||
93 | + | ||
94 | + def possible_domains | ||
95 | + environment.domains | ||
96 | + end | ||
97 | + | ||
98 | + def person? | ||
99 | + true | ||
100 | + end | ||
101 | + | ||
102 | + def contact_email(*args) | ||
103 | + self.email | ||
104 | + end | ||
105 | + | ||
106 | + def notification_emails | ||
107 | + [self.contact_email] | ||
108 | + end | ||
109 | + | ||
110 | + def email_domain | ||
111 | + self.source | ||
112 | + end | ||
113 | + | ||
114 | + def email_addresses | ||
115 | + ['%s@%s' % [self.identifier, self.source] ] | ||
116 | + end | ||
117 | + | ||
118 | + def jid(options = {}) | ||
119 | + "#{self.identifier}@#{self.source}" | ||
120 | + end | ||
121 | + def full_jid(options = {}) | ||
122 | + "#{jid(options)}/#{self.name}" | ||
123 | + end | ||
124 | + | ||
125 | + class ExternalPerson::Image | ||
126 | + def initialize(path) | ||
127 | + @path = path | ||
128 | + end | ||
129 | + | ||
130 | + def public_filename(size = nil) | ||
131 | + URI.join(@path, size.to_s) | ||
132 | + end | ||
133 | + | ||
134 | + def content_type | ||
135 | + # This is not really going to be used anywhere that matters | ||
136 | + # so we are hardcodding it here. | ||
137 | + 'image/png' | ||
138 | + end | ||
139 | + end | ||
140 | + | ||
141 | + def image | ||
142 | + ExternalPerson::Image.new(avatar) | ||
143 | + end | ||
144 | + | ||
145 | + def data_hash(gravatar_default = nil) | ||
146 | + friends_list = {} | ||
147 | + { | ||
148 | + 'login' => self.identifier, | ||
149 | + 'name' => self.name, | ||
150 | + 'email' => self.email, | ||
151 | + 'avatar' => self.profile_custom_icon(gravatar_default), | ||
152 | + 'is_admin' => self.is_admin?, | ||
153 | + 'since_month' => self.created_at.month, | ||
154 | + 'since_year' => self.created_at.year, | ||
155 | + 'email_domain' => self.source, | ||
156 | + 'friends_list' => friends_list, | ||
157 | + 'enterprises' => [], | ||
158 | + 'amount_of_friends' => friends_list.count, | ||
159 | + 'chat_enabled' => false | ||
160 | + } | ||
161 | + end | ||
162 | + | ||
163 | + # External Person should respond to all methods in Person and Profile | ||
164 | + def person_instance_methods | ||
165 | + methods_and_responses = { | ||
166 | + enterprises: Enterprise.none, communities: Community.none, friends: | ||
167 | + Person.none, memberships: Profile.none, friendships: Person.none, | ||
168 | + following_articles: Article.none, article_followers: ArticleFollower.none, | ||
169 | + requested_tasks: Task.none, mailings: Mailing.none, scraps_sent: | ||
170 | + Scrap.none, favorite_enterprise_people: FavoriteEnterprisePerson.none, | ||
171 | + favorite_enterprises: Enterprise.none, acepted_forums: Forum.none, | ||
172 | + articles_with_access: Article.none, suggested_profiles: | ||
173 | + ProfileSuggestion.none, suggested_people: ProfileSuggestion.none, | ||
174 | + suggested_communities: ProfileSuggestion.none, user: nil, | ||
175 | + refused_communities: Community.none, has_permission?: false, | ||
176 | + has_permission_with_admin?: false, has_permission_without_admin?: false, | ||
177 | + has_permission_with_plugins?: false, has_permission_without_plugins?: | ||
178 | + false, memberships_by_role: Person.none, can_change_homepage?: false, | ||
179 | + can_control_scrap?: false, receives_scrap_notification?: false, | ||
180 | + can_control_activity?: false, can_post_content?: false, | ||
181 | + suggested_friend_groups: [], friend_groups: [], add_friend: nil, | ||
182 | + already_request_friendship?: false, remove_friend: nil, | ||
183 | + presence_of_required_fields: nil, active_fields: [], required_fields: [], | ||
184 | + signup_fields: [], default_set_of_blocks: [], default_set_of_boxes: [], | ||
185 | + default_set_of_articles: [], cell_phone: nil, comercial_phone: nil, | ||
186 | + nationality: nil, schooling: nil, contact_information: nil, sex: nil, | ||
187 | + birth_date: nil, jabber_id: nil, personal_website: nil, address_reference: | ||
188 | + nil, district: nil, schooling_status: nil, formation: nil, | ||
189 | + custom_formation: nil, area_of_study: nil, custom_area_of_study: nil, | ||
190 | + professional_activity: nil, organization_website: nil, organization: nil, | ||
191 | + photo: nil, city: nil, state: nil, country: nil, zip_code: nil, | ||
192 | + address_line2: nil, copy_communities_from: nil, | ||
193 | + has_organization_pending_tasks?: false, organizations_with_pending_tasks: | ||
194 | + Organization.none, pending_tasks_for_organization: Task.none, | ||
195 | + build_contact: nil, is_a_friend?: false, ask_to_join?: false, refuse_join: | ||
196 | + nil, blocks_to_expire_cache: [], cache_keys: [], communities_cache_key: '', | ||
197 | + friends_cache_key: '', manage_friends_cache_key: '', | ||
198 | + relationships_cache_key: '', is_member_of?: false, follows?: false, | ||
199 | + each_friend: nil, is_last_admin?: false, is_last_admin_leaving?: false, | ||
200 | + leave: nil, last_notification: nil, notification_time: 0, notifier: nil, | ||
201 | + remove_suggestion: nil, allow_invitation_from?: false | ||
202 | + } | ||
203 | + | ||
204 | + derivated_methods = generate_derivated_methods(methods_and_responses) | ||
205 | + derivated_methods.merge(methods_and_responses) | ||
206 | + end | ||
207 | + | ||
208 | + def profile_instance_methods | ||
209 | + methods_and_responses = { | ||
210 | + role_assignments: RoleAssignment.none, favorite_enterprises: | ||
211 | + Enterprise.none, memberships: Profile.none, friendships: Profile.none, | ||
212 | + tasks: Task.none, suggested_profiles: ProfileSuggestion.none, | ||
213 | + suggested_people: ProfileSuggestion.none, suggested_communities: | ||
214 | + ProfileSuggestion.none, public_profile: true, nickname: nil, custom_footer: | ||
215 | + '', custom_header: '', address: '', zip_code: '', contact_phone: '', | ||
216 | + image_builder: nil, description: '', closed: false, template_id: nil, lat: | ||
217 | + nil, lng: nil, is_template: false, fields_privacy: {}, preferred_domain_id: | ||
218 | + nil, category_ids: [], country: '', city: '', state: '', | ||
219 | + national_region_code: '', redirect_l10n: false, notification_time: 0, | ||
220 | + custom_url_redirection: nil, email_suggestions: false, | ||
221 | + allow_members_to_invite: false, invite_friends_only: false, secret: false, | ||
222 | + profile_admin_mail_notification: false, redirection_after_login: nil, | ||
223 | + profile_activities: ProfileActivity.none, action_tracker_notifications: | ||
224 | + ActionTrackerNotification.none, tracked_notifications: | ||
225 | + ActionTracker::Record.none, scraps_received: Scrap.none, template: | ||
226 | + Profile.none, comments_received: Comment.none, email_templates: | ||
227 | + EmailTemplate.none, members: Profile.none, members_like: Profile.none, | ||
228 | + members_by: Profile.none, members_by_role: Profile.none, scraps: | ||
229 | + Scrap.none, welcome_page_content: nil, settings: {}, find_in_all_tasks: | ||
230 | + nil, top_level_categorization: {}, interests: Category.none, geolocation: | ||
231 | + '', country_name: '', pending_categorizations: [], add_category: false, | ||
232 | + create_pending_categorizations: false, top_level_articles: Article.none, | ||
233 | + valid_identifier: true, valid_template: false, create_default_set_of_boxes: | ||
234 | + true, copy_blocks_from: nil, default_template: nil, | ||
235 | + template_without_default: nil, template_with_default: nil, apply_template: | ||
236 | + false, iframe_whitelist: [], recent_documents: Article.none, last_articles: | ||
237 | + Article.none, is_validation_entity?: false, hostname: nil, own_hostname: | ||
238 | + nil, article_tags: {}, tagged_with: Article.none, | ||
239 | + insert_default_article_set: false, copy_articles_from: true, | ||
240 | + copy_article_tree: nil, copy_article?: false, add_member: false, | ||
241 | + remove_member: false, add_admin: false, remove_admin: false, add_moderator: | ||
242 | + false, display_info_to?: true, update_category_from_region: nil, | ||
243 | + accept_category?: false, custom_header_expanded: '', | ||
244 | + custom_footer_expanded: '', public?: true, themes: [], find_theme: nil, | ||
245 | + blogs: Blog.none, blog: nil, has_blog?: false, forums: Forum.none, forum: | ||
246 | + nil, has_forum?: false, admins: [], settings_field: {}, setting_changed: | ||
247 | + false, public_content: true, enable_contact?: false, folder_types: [], | ||
248 | + folders: Article.none, image_galleries: Article.none, image_valid: true, | ||
249 | + update_header_and_footer: nil, update_theme: nil, update_layout_template: | ||
250 | + nil, recent_actions: ActionTracker::Record.none, recent_notifications: | ||
251 | + ActionTracker::Record.none, more_active_label: _('no activity'), | ||
252 | + more_popular_label: _('no members'), profile_custom_image: nil, | ||
253 | + is_on_homepage?: false, activities: ProfileActivity.none, | ||
254 | + may_display_field_to?: true, may_display_location_to?: true, public_fields: | ||
255 | + {}, followed_by?: false, display_private_info_to?: true, can_view_field?: | ||
256 | + true, remove_from_suggestion_list: nil, layout_template: 'default', | ||
257 | + is_admin?: false, add_friend: false, follows?: false, is_a_friend?: false, | ||
258 | + already_request_friendship?: false | ||
259 | + } | ||
260 | + | ||
261 | + derivated_methods = generate_derivated_methods(methods_and_responses) | ||
262 | + derivated_methods.merge(methods_and_responses) | ||
263 | + end | ||
264 | + | ||
265 | + def method_missing(method, *args, &block) | ||
266 | + if person_instance_methods.keys.include?(method) | ||
267 | + return person_instance_methods[method] | ||
268 | + end | ||
269 | + if profile_instance_methods.keys.include? method | ||
270 | + return profile_instance_methods[method] | ||
271 | + end | ||
272 | + end | ||
273 | + | ||
274 | + def respond_to_missing?(method_name, include_private = false) | ||
275 | + person_instance_methods.keys.include?(method_name) || | ||
276 | + profile_instance_methods.keys.include?(method_name) || | ||
277 | + super | ||
278 | + end | ||
279 | + | ||
280 | + private | ||
281 | + | ||
282 | + def generate_derivated_methods(methods) | ||
283 | + derivated_methods = {} | ||
284 | + methods.keys.each do |method| | ||
285 | + derivated_methods[method.to_s.insert(-1, '?').to_sym] = false | ||
286 | + derivated_methods[method.to_s.insert(-1, '=').to_sym] = nil | ||
287 | + end | ||
288 | + derivated_methods | ||
289 | + end | ||
290 | +end |
app/models/person.rb
1 | # A person is the profile of an user holding all relationships with the rest of the system | 1 | # A person is the profile of an user holding all relationships with the rest of the system |
2 | class Person < Profile | 2 | class Person < Profile |
3 | 3 | ||
4 | + include Human | ||
5 | + | ||
4 | attr_accessible :organization, :contact_information, :sex, :birth_date, :cell_phone, :comercial_phone, :jabber_id, :personal_website, :nationality, :address_reference, :district, :schooling, :schooling_status, :formation, :custom_formation, :area_of_study, :custom_area_of_study, :professional_activity, :organization_website, :following_articles | 6 | attr_accessible :organization, :contact_information, :sex, :birth_date, :cell_phone, :comercial_phone, :jabber_id, :personal_website, :nationality, :address_reference, :district, :schooling, :schooling_status, :formation, :custom_formation, :area_of_study, :custom_area_of_study, :professional_activity, :organization_website, :following_articles |
5 | 7 | ||
6 | SEARCH_FILTERS = { | 8 | SEARCH_FILTERS = { |
@@ -88,7 +90,6 @@ class Person < Profile | @@ -88,7 +90,6 @@ class Person < Profile | ||
88 | memberships.where('role_assignments.role_id = ?', role.id) | 90 | memberships.where('role_assignments.role_id = ?', role.id) |
89 | end | 91 | end |
90 | 92 | ||
91 | - has_many :comments, :foreign_key => :author_id | ||
92 | has_many :article_followers, :dependent => :destroy | 93 | has_many :article_followers, :dependent => :destroy |
93 | has_many :following_articles, :class_name => 'Article', :through => :article_followers, :source => :article | 94 | has_many :following_articles, :class_name => 'Article', :through => :article_followers, :source => :article |
94 | has_many :friendships, :dependent => :destroy | 95 | has_many :friendships, :dependent => :destroy |
@@ -100,8 +101,6 @@ class Person < Profile | @@ -100,8 +101,6 @@ class Person < Profile | ||
100 | 101 | ||
101 | has_many :requested_tasks, :class_name => 'Task', :foreign_key => :requestor_id, :dependent => :destroy | 102 | has_many :requested_tasks, :class_name => 'Task', :foreign_key => :requestor_id, :dependent => :destroy |
102 | 103 | ||
103 | - has_many :abuse_reports, :foreign_key => 'reporter_id', :dependent => :destroy | ||
104 | - | ||
105 | has_many :mailings | 104 | has_many :mailings |
106 | 105 | ||
107 | has_many :scraps_sent, :class_name => 'Scrap', :foreign_key => :sender_id, :dependent => :destroy | 106 | has_many :scraps_sent, :class_name => 'Scrap', :foreign_key => :sender_id, :dependent => :destroy |
@@ -123,15 +122,6 @@ class Person < Profile | @@ -123,15 +122,6 @@ class Person < Profile | ||
123 | 122 | ||
124 | scope :more_popular, -> { order 'friends_count DESC' } | 123 | scope :more_popular, -> { order 'friends_count DESC' } |
125 | 124 | ||
126 | - scope :abusers, -> { | ||
127 | - joins(:abuse_complaints).where('tasks.status = 3').distinct.select('profiles.*') | ||
128 | - } | ||
129 | - scope :non_abusers, -> { | ||
130 | - distinct.select("profiles.*"). | ||
131 | - joins("LEFT JOIN tasks ON profiles.id = tasks.requestor_id AND tasks.type='AbuseComplaint'"). | ||
132 | - where("tasks.status != 3 OR tasks.id is NULL") | ||
133 | - } | ||
134 | - | ||
135 | scope :admins, -> { joins(:role_assignments => :role).where('roles.key = ?', 'environment_administrator') } | 125 | scope :admins, -> { joins(:role_assignments => :role).where('roles.key = ?', 'environment_administrator') } |
136 | scope :activated, -> { joins(:user).where('users.activation_code IS NULL AND users.activated_at IS NOT NULL') } | 126 | scope :activated, -> { joins(:user).where('users.activation_code IS NULL AND users.activated_at IS NOT NULL') } |
137 | scope :deactivated, -> { joins(:user).where('NOT (users.activation_code IS NULL AND users.activated_at IS NOT NULL)') } | 127 | scope :deactivated, -> { joins(:user).where('NOT (users.activation_code IS NULL AND users.activated_at IS NOT NULL)') } |
@@ -174,15 +164,6 @@ class Person < Profile | @@ -174,15 +164,6 @@ class Person < Profile | ||
174 | (self.has_permission?('post_content', profile) || self.has_permission?('publish_content', profile)) | 164 | (self.has_permission?('post_content', profile) || self.has_permission?('publish_content', profile)) |
175 | end | 165 | end |
176 | 166 | ||
177 | - # Sets the identifier for this person. Raises an exception when called on a | ||
178 | - # existing person (since peoples' identifiers cannot be changed) | ||
179 | - def identifier=(value) | ||
180 | - unless self.new_record? | ||
181 | - raise ArgumentError.new(_('An existing person cannot be renamed.')) | ||
182 | - end | ||
183 | - self[:identifier] = value | ||
184 | - end | ||
185 | - | ||
186 | def suggested_friend_groups | 167 | def suggested_friend_groups |
187 | (friend_groups.compact + [ _('friends'), _('work'), _('school'), _('family') ]).map {|i| i if !i.empty?}.compact.uniq | 168 | (friend_groups.compact + [ _('friends'), _('work'), _('school'), _('family') ]).map {|i| i if !i.empty?}.compact.uniq |
188 | end | 169 | end |
@@ -192,7 +173,7 @@ class Person < Profile | @@ -192,7 +173,7 @@ class Person < Profile | ||
192 | end | 173 | end |
193 | 174 | ||
194 | def add_friend(friend, group = nil) | 175 | def add_friend(friend, group = nil) |
195 | - unless self.is_a_friend?(friend) | 176 | + unless self.is_a_friend?(friend) || friend.is_a?(ExternalPerson) |
196 | friendship = self.friendships.build | 177 | friendship = self.friendships.build |
197 | friendship.friend = friend | 178 | friendship.friend = friend |
198 | friendship.group = group | 179 | friendship.group = group |
@@ -517,21 +498,6 @@ class Person < Profile | @@ -517,21 +498,6 @@ class Person < Profile | ||
517 | leave_hash.to_json | 498 | leave_hash.to_json |
518 | end | 499 | end |
519 | 500 | ||
520 | - def already_reported?(profile) | ||
521 | - abuse_reports.any? { |report| report.abuse_complaint.reported == profile && report.abuse_complaint.opened? } | ||
522 | - end | ||
523 | - | ||
524 | - def register_report(abuse_report, profile) | ||
525 | - AbuseComplaint.create!(:reported => profile, :target => profile.environment) if !profile.opened_abuse_complaint | ||
526 | - abuse_report.abuse_complaint = profile.opened_abuse_complaint | ||
527 | - abuse_report.reporter = self | ||
528 | - abuse_report.save! | ||
529 | - end | ||
530 | - | ||
531 | - def abuser? | ||
532 | - AbuseComplaint.finished.where(:requestor_id => self).count > 0 | ||
533 | - end | ||
534 | - | ||
535 | def control_panel_settings_button | 501 | def control_panel_settings_button |
536 | {:title => _('Edit Profile'), :icon => 'edit-profile'} | 502 | {:title => _('Edit Profile'), :icon => 'edit-profile'} |
537 | end | 503 | end |
@@ -580,6 +546,34 @@ class Person < Profile | @@ -580,6 +546,34 @@ class Person < Profile | ||
580 | person.has_permission?(:manage_friends, self) | 546 | person.has_permission?(:manage_friends, self) |
581 | end | 547 | end |
582 | 548 | ||
549 | + def data_hash(gravatar_default = nil) | ||
550 | + friends_list = {} | ||
551 | + enterprises = self.enterprises.map { |e| { 'name' => e.short_name, 'identifier' => e.identifier } } | ||
552 | + self.friends.online.map do |person| | ||
553 | + friends_list[person.identifier] = { | ||
554 | + 'avatar' => person.profile_custom_icon(gravatar_default), | ||
555 | + 'name' => person.short_name, | ||
556 | + 'jid' => person.full_jid, | ||
557 | + 'status' => person.user.chat_status, | ||
558 | + } | ||
559 | + end | ||
560 | + | ||
561 | + { | ||
562 | + 'login' => self.identifier, | ||
563 | + 'name' => self.name, | ||
564 | + 'email' => self.email, | ||
565 | + 'avatar' => self.profile_custom_icon(gravatar_default), | ||
566 | + 'is_admin' => self.is_admin?, | ||
567 | + 'since_month' => self.created_at.month, | ||
568 | + 'since_year' => self.created_at.year, | ||
569 | + 'email_domain' => self.user.enable_email ? self.user.email_domain : nil, | ||
570 | + 'friends_list' => friends_list, | ||
571 | + 'enterprises' => enterprises, | ||
572 | + 'amount_of_friends' => friends_list.count, | ||
573 | + 'chat_enabled' => self.environment.enabled?('xmpp_chat') | ||
574 | + } | ||
575 | + end | ||
576 | + | ||
583 | protected | 577 | protected |
584 | 578 | ||
585 | def followed_by?(profile) | 579 | def followed_by?(profile) |
app/models/profile.rb
@@ -3,9 +3,10 @@ | @@ -3,9 +3,10 @@ | ||
3 | # which by default is the one returned by Environment:default. | 3 | # which by default is the one returned by Environment:default. |
4 | class Profile < ApplicationRecord | 4 | class Profile < ApplicationRecord |
5 | 5 | ||
6 | - attr_accessible :name, :identifier, :public_profile, :nickname, :custom_footer, :custom_header, :address, :zip_code, :contact_phone, :image_builder, :description, :closed, :template_id, :environment, :lat, :lng, :is_template, :fields_privacy, :preferred_domain_id, :category_ids, :country, :city, :state, :national_region_code, :email, :contact_email, :redirect_l10n, :notification_time, | ||
7 | - :redirection_after_login, :custom_url_redirection, | ||
8 | - :email_suggestions, :allow_members_to_invite, :invite_friends_only, :secret, :profile_admin_mail_notification | 6 | + include ProfileEntity |
7 | + | ||
8 | + attr_accessible :public_profile, :nickname, :custom_footer, :custom_header, :address, :zip_code, :contact_phone, :image_builder, :description, :closed, :template_id, :lat, :lng, :is_template, :fields_privacy, :preferred_domain_id, :category_ids, :country, :city, :state, :national_region_code, :email, :contact_email, :redirect_l10n, :notification_time, | ||
9 | + :custom_url_redirection, :email_suggestions, :allow_members_to_invite, :invite_friends_only, :secret, :profile_admin_mail_notification, :redirection_after_login | ||
9 | 10 | ||
10 | # use for internationalizable human type names in search facets | 11 | # use for internationalizable human type names in search facets |
11 | # reimplement on subclasses | 12 | # reimplement on subclasses |
@@ -115,8 +116,6 @@ class Profile < ApplicationRecord | @@ -115,8 +116,6 @@ class Profile < ApplicationRecord | ||
115 | } | 116 | } |
116 | scope :no_templates, -> { where is_template: false } | 117 | scope :no_templates, -> { where is_template: false } |
117 | 118 | ||
118 | - scope :recent, -> limit=nil { order('id DESC').limit(limit) } | ||
119 | - | ||
120 | 119 | ||
121 | # Returns a scoped object to select profiles in a given location or in a radius | 120 | # Returns a scoped object to select profiles in a given location or in a radius |
122 | # distance from the given location center. | 121 | # distance from the given location center. |
@@ -224,8 +223,6 @@ class Profile < ApplicationRecord | @@ -224,8 +223,6 @@ class Profile < ApplicationRecord | ||
224 | welcome_page && welcome_page.published ? welcome_page.body : nil | 223 | welcome_page && welcome_page.published ? welcome_page.body : nil |
225 | end | 224 | end |
226 | 225 | ||
227 | - has_many :search_terms, :as => :context | ||
228 | - | ||
229 | def scraps(scrap=nil) | 226 | def scraps(scrap=nil) |
230 | scrap = scrap.is_a?(Scrap) ? scrap.id : scrap | 227 | scrap = scrap.is_a?(Scrap) ? scrap.id : scrap |
231 | scrap.nil? ? Scrap.all_scraps(self) : Scrap.all_scraps(self).find(scrap) | 228 | scrap.nil? ? Scrap.all_scraps(self) : Scrap.all_scraps(self).find(scrap) |
@@ -278,7 +275,6 @@ class Profile < ApplicationRecord | @@ -278,7 +275,6 @@ class Profile < ApplicationRecord | ||
278 | 275 | ||
279 | has_many :domains, :as => :owner | 276 | has_many :domains, :as => :owner |
280 | belongs_to :preferred_domain, :class_name => 'Domain', :foreign_key => 'preferred_domain_id' | 277 | belongs_to :preferred_domain, :class_name => 'Domain', :foreign_key => 'preferred_domain_id' |
281 | - belongs_to :environment | ||
282 | 278 | ||
283 | has_many :articles, :dependent => :destroy | 279 | has_many :articles, :dependent => :destroy |
284 | belongs_to :home_page, :class_name => Article.name, :foreign_key => 'home_page_id' | 280 | belongs_to :home_page, :class_name => Article.name, :foreign_key => 'home_page_id' |
@@ -305,8 +301,6 @@ class Profile < ApplicationRecord | @@ -305,8 +301,6 @@ class Profile < ApplicationRecord | ||
305 | has_many :profile_categorizations_including_virtual, :class_name => 'ProfileCategorization' | 301 | has_many :profile_categorizations_including_virtual, :class_name => 'ProfileCategorization' |
306 | has_many :categories_including_virtual, :through => :profile_categorizations_including_virtual, :source => :category | 302 | has_many :categories_including_virtual, :through => :profile_categorizations_including_virtual, :source => :category |
307 | 303 | ||
308 | - has_many :abuse_complaints, :foreign_key => 'requestor_id', :dependent => :destroy | ||
309 | - | ||
310 | has_many :profile_suggestions, :foreign_key => :suggestion_id, :dependent => :destroy | 304 | has_many :profile_suggestions, :foreign_key => :suggestion_id, :dependent => :destroy |
311 | 305 | ||
312 | def top_level_categorization | 306 | def top_level_categorization |
@@ -401,7 +395,6 @@ class Profile < ApplicationRecord | @@ -401,7 +395,6 @@ class Profile < ApplicationRecord | ||
401 | self.all | 395 | self.all |
402 | end | 396 | end |
403 | 397 | ||
404 | - validates_presence_of :identifier, :name | ||
405 | validates_length_of :nickname, :maximum => 16, :allow_nil => true | 398 | validates_length_of :nickname, :maximum => 16, :allow_nil => true |
406 | validate :valid_template | 399 | validate :valid_template |
407 | validate :valid_identifier | 400 | validate :valid_identifier |
@@ -416,14 +409,6 @@ class Profile < ApplicationRecord | @@ -416,14 +409,6 @@ class Profile < ApplicationRecord | ||
416 | end | 409 | end |
417 | end | 410 | end |
418 | 411 | ||
419 | - before_create :set_default_environment | ||
420 | - def set_default_environment | ||
421 | - if self.environment.nil? | ||
422 | - self.environment = Environment.default | ||
423 | - end | ||
424 | - true | ||
425 | - end | ||
426 | - | ||
427 | # registar callback for creating boxes after the object is created. | 412 | # registar callback for creating boxes after the object is created. |
428 | after_create :create_default_set_of_boxes | 413 | after_create :create_default_set_of_boxes |
429 | 414 | ||
@@ -496,9 +481,6 @@ class Profile < ApplicationRecord | @@ -496,9 +481,6 @@ class Profile < ApplicationRecord | ||
496 | self.save(:validate => false) | 481 | self.save(:validate => false) |
497 | end | 482 | end |
498 | 483 | ||
499 | - def apply_type_specific_template(template) | ||
500 | - end | ||
501 | - | ||
502 | xss_terminate :only => [ :name, :nickname, :address, :contact_phone, :description ], :on => 'validation' | 484 | xss_terminate :only => [ :name, :nickname, :address, :contact_phone, :description ], :on => 'validation' |
503 | xss_terminate :only => [ :custom_footer, :custom_header ], :with => 'white_list' | 485 | xss_terminate :only => [ :custom_footer, :custom_header ], :with => 'white_list' |
504 | 486 | ||
@@ -539,10 +521,6 @@ class Profile < ApplicationRecord | @@ -539,10 +521,6 @@ class Profile < ApplicationRecord | ||
539 | ).order('articles.published_at desc, articles.id desc') | 521 | ).order('articles.published_at desc, articles.id desc') |
540 | end | 522 | end |
541 | 523 | ||
542 | - def to_liquid | ||
543 | - HashWithIndifferentAccess.new :name => name, :identifier => identifier | ||
544 | - end | ||
545 | - | ||
546 | class << self | 524 | class << self |
547 | 525 | ||
548 | # finds a profile by its identifier. This method is a shortcut to | 526 | # finds a profile by its identifier. This method is a shortcut to |
@@ -562,23 +540,6 @@ class Profile < ApplicationRecord | @@ -562,23 +540,6 @@ class Profile < ApplicationRecord | ||
562 | environment | 540 | environment |
563 | end | 541 | end |
564 | 542 | ||
565 | - # returns +false+ | ||
566 | - def person? | ||
567 | - self.kind_of?(Person) | ||
568 | - end | ||
569 | - | ||
570 | - def enterprise? | ||
571 | - self.kind_of?(Enterprise) | ||
572 | - end | ||
573 | - | ||
574 | - def organization? | ||
575 | - self.kind_of?(Organization) | ||
576 | - end | ||
577 | - | ||
578 | - def community? | ||
579 | - self.kind_of?(Community) | ||
580 | - end | ||
581 | - | ||
582 | # returns false. | 543 | # returns false. |
583 | def is_validation_entity? | 544 | def is_validation_entity? |
584 | false | 545 | false |
@@ -683,13 +644,6 @@ private :generate_url, :url_options | @@ -683,13 +644,6 @@ private :generate_url, :url_options | ||
683 | self.articles.tagged_with(tag) | 644 | self.articles.tagged_with(tag) |
684 | end | 645 | end |
685 | 646 | ||
686 | - # Tells whether a specified profile has members or nor. | ||
687 | - # | ||
688 | - # On this class, returns <tt>false</tt> by default. | ||
689 | - def has_members? | ||
690 | - false | ||
691 | - end | ||
692 | - | ||
693 | after_create :insert_default_article_set | 647 | after_create :insert_default_article_set |
694 | def insert_default_article_set | 648 | def insert_default_article_set |
695 | if template | 649 | if template |
@@ -704,23 +658,6 @@ private :generate_url, :url_options | @@ -704,23 +658,6 @@ private :generate_url, :url_options | ||
704 | end | 658 | end |
705 | end | 659 | end |
706 | 660 | ||
707 | - # Override this method in subclasses of Profile to create a default article | ||
708 | - # set upon creation. Note that this method will be called *only* if there is | ||
709 | - # no template for the type of profile (i.e. if the template was removed or in | ||
710 | - # the creation of the template itself). | ||
711 | - # | ||
712 | - # This method must return an array of pre-populated articles, which will be | ||
713 | - # associated to the profile before being saved. Example: | ||
714 | - # | ||
715 | - # def default_set_of_articles | ||
716 | - # [Blog.new(:name => 'Blog'), Gallery.new(:name => 'Gallery')] | ||
717 | - # end | ||
718 | - # | ||
719 | - # By default, this method returns an empty array. | ||
720 | - def default_set_of_articles | ||
721 | - [] | ||
722 | - end | ||
723 | - | ||
724 | def copy_articles_from other | 661 | def copy_articles_from other |
725 | return false if other.top_level_articles.empty? | 662 | return false if other.top_level_articles.empty? |
726 | other.top_level_articles.each do |a| | 663 | other.top_level_articles.each do |a| |
@@ -816,19 +753,6 @@ private :generate_url, :url_options | @@ -816,19 +753,6 @@ private :generate_url, :url_options | ||
816 | !forbidden.include?(cat.class) | 753 | !forbidden.include?(cat.class) |
817 | end | 754 | end |
818 | 755 | ||
819 | - include ActionView::Helpers::TextHelper | ||
820 | - def short_name(chars = 40) | ||
821 | - if self[:nickname].blank? | ||
822 | - if chars | ||
823 | - truncate self.name, length: chars, omission: '...' | ||
824 | - else | ||
825 | - self.name | ||
826 | - end | ||
827 | - else | ||
828 | - self[:nickname] | ||
829 | - end | ||
830 | - end | ||
831 | - | ||
832 | def custom_header | 756 | def custom_header |
833 | self[:custom_header] || environment && environment.custom_header | 757 | self[:custom_header] || environment && environment.custom_header |
834 | end | 758 | end |
@@ -934,14 +858,6 @@ private :generate_url, :url_options | @@ -934,14 +858,6 @@ private :generate_url, :url_options | ||
934 | articles.galleries | 858 | articles.galleries |
935 | end | 859 | end |
936 | 860 | ||
937 | - def blocks_to_expire_cache | ||
938 | - [] | ||
939 | - end | ||
940 | - | ||
941 | - def cache_keys(params = {}) | ||
942 | - [] | ||
943 | - end | ||
944 | - | ||
945 | validate :image_valid | 861 | validate :image_valid |
946 | 862 | ||
947 | def image_valid | 863 | def image_valid |
@@ -978,16 +894,6 @@ private :generate_url, :url_options | @@ -978,16 +894,6 @@ private :generate_url, :url_options | ||
978 | self.update_attribute(:layout_template, template) | 894 | self.update_attribute(:layout_template, template) |
979 | end | 895 | end |
980 | 896 | ||
981 | - def members_cache_key(params = {}) | ||
982 | - page = params[:npage] || '1' | ||
983 | - sort = (params[:sort] == 'desc') ? params[:sort] : 'asc' | ||
984 | - cache_key + '-members-page-' + page + '-' + sort | ||
985 | - end | ||
986 | - | ||
987 | - def more_recent_label | ||
988 | - _("Since: ") | ||
989 | - end | ||
990 | - | ||
991 | def recent_actions | 897 | def recent_actions |
992 | tracked_actions.recent | 898 | tracked_actions.recent |
993 | end | 899 | end |
@@ -1042,32 +948,6 @@ private :generate_url, :url_options | @@ -1042,32 +948,6 @@ private :generate_url, :url_options | ||
1042 | end | 948 | end |
1043 | end | 949 | end |
1044 | 950 | ||
1045 | - def opened_abuse_complaint | ||
1046 | - abuse_complaints.opened.first | ||
1047 | - end | ||
1048 | - | ||
1049 | - def disable | ||
1050 | - self.visible = false | ||
1051 | - self.save | ||
1052 | - end | ||
1053 | - | ||
1054 | - def enable | ||
1055 | - self.visible = true | ||
1056 | - self.save | ||
1057 | - end | ||
1058 | - | ||
1059 | - def control_panel_settings_button | ||
1060 | - {:title => _('Edit Profile'), :icon => 'edit-profile'} | ||
1061 | - end | ||
1062 | - | ||
1063 | - def self.identification | ||
1064 | - name | ||
1065 | - end | ||
1066 | - | ||
1067 | - def exclude_verbs_on_activities | ||
1068 | - %w[] | ||
1069 | - end | ||
1070 | - | ||
1071 | # Customize in subclasses | 951 | # Customize in subclasses |
1072 | def activities | 952 | def activities |
1073 | self.profile_activities.includes(:activity).order('updated_at DESC') | 953 | self.profile_activities.includes(:activity).order('updated_at DESC') |
@@ -1102,10 +982,6 @@ private :generate_url, :url_options | @@ -1102,10 +982,6 @@ private :generate_url, :url_options | ||
1102 | self.active_fields | 982 | self.active_fields |
1103 | end | 983 | end |
1104 | 984 | ||
1105 | - def control_panel_settings_button | ||
1106 | - {:title => _('Profile Info and settings'), :icon => 'edit-profile'} | ||
1107 | - end | ||
1108 | - | ||
1109 | def followed_by?(person) | 985 | def followed_by?(person) |
1110 | person.is_member_of?(self) | 986 | person.is_member_of?(self) |
1111 | end | 987 | end |
@@ -1133,19 +1009,4 @@ private :generate_url, :url_options | @@ -1133,19 +1009,4 @@ private :generate_url, :url_options | ||
1133 | suggestion.disable if suggestion | 1009 | suggestion.disable if suggestion |
1134 | end | 1010 | end |
1135 | 1011 | ||
1136 | - def allow_invitation_from(person) | ||
1137 | - false | ||
1138 | - end | ||
1139 | - | ||
1140 | - def allow_post_content?(person = nil) | ||
1141 | - person.kind_of?(Profile) && person.has_permission?('post_content', self) | ||
1142 | - end | ||
1143 | - | ||
1144 | - def allow_edit?(person = nil) | ||
1145 | - person.kind_of?(Profile) && person.has_permission?('edit_profile', self) | ||
1146 | - end | ||
1147 | - | ||
1148 | - def allow_destroy?(person = nil) | ||
1149 | - person.kind_of?(Profile) && person.has_permission?('destroy_profile', self) | ||
1150 | - end | ||
1151 | end | 1012 | end |
app/models/user.rb
@@ -7,6 +7,8 @@ class User < ApplicationRecord | @@ -7,6 +7,8 @@ class User < ApplicationRecord | ||
7 | 7 | ||
8 | attr_accessible :login, :email, :password, :password_confirmation, :activated_at | 8 | attr_accessible :login, :email, :password, :password_confirmation, :activated_at |
9 | 9 | ||
10 | + include ExternalUser | ||
11 | + | ||
10 | N_('Password') | 12 | N_('Password') |
11 | N_('Password confirmation') | 13 | N_('Password confirmation') |
12 | N_('Terms accepted') | 14 | N_('Terms accepted') |
@@ -105,6 +107,8 @@ class User < ApplicationRecord | @@ -105,6 +107,8 @@ class User < ApplicationRecord | ||
105 | has_one :person, dependent: :destroy, autosave: false | 107 | has_one :person, dependent: :destroy, autosave: false |
106 | belongs_to :environment | 108 | belongs_to :environment |
107 | 109 | ||
110 | + alias_method_chain :person, :external | ||
111 | + | ||
108 | has_many :sessions, dependent: :destroy | 112 | has_many :sessions, dependent: :destroy |
109 | # holds the current session, see lib/authenticated_system.rb | 113 | # holds the current session, see lib/authenticated_system.rb |
110 | attr_accessor :session | 114 | attr_accessor :session |
@@ -146,7 +150,8 @@ class User < ApplicationRecord | @@ -146,7 +150,8 @@ class User < ApplicationRecord | ||
146 | u.generate_private_token_if_not_exist | 150 | u.generate_private_token_if_not_exist |
147 | return u | 151 | return u |
148 | end | 152 | end |
149 | - return nil | 153 | + |
154 | + return User.external_authenticate(login, password, environment) | ||
150 | end | 155 | end |
151 | 156 | ||
152 | def register_login | 157 | def register_login |
@@ -380,31 +385,7 @@ class User < ApplicationRecord | @@ -380,31 +385,7 @@ class User < ApplicationRecord | ||
380 | end | 385 | end |
381 | 386 | ||
382 | def data_hash(gravatar_default = nil) | 387 | def data_hash(gravatar_default = nil) |
383 | - friends_list = {} | ||
384 | - enterprises = person.enterprises.map { |e| { 'name' => e.short_name, 'identifier' => e.identifier } } | ||
385 | - self.person.friends.online.map do |person| | ||
386 | - friends_list[person.identifier] = { | ||
387 | - 'avatar' => person.profile_custom_icon(gravatar_default), | ||
388 | - 'name' => person.short_name, | ||
389 | - 'jid' => person.full_jid, | ||
390 | - 'status' => person.user.chat_status, | ||
391 | - } | ||
392 | - end | ||
393 | - | ||
394 | - { | ||
395 | - 'login' => self.login, | ||
396 | - 'name' => self.person.name, | ||
397 | - 'email' => self.email, | ||
398 | - 'avatar' => self.person.profile_custom_icon(gravatar_default), | ||
399 | - 'is_admin' => self.person.is_admin?, | ||
400 | - 'since_month' => self.person.created_at.month, | ||
401 | - 'since_year' => self.person.created_at.year, | ||
402 | - 'email_domain' => self.enable_email ? self.email_domain : nil, | ||
403 | - 'friends_list' => friends_list, | ||
404 | - 'enterprises' => enterprises, | ||
405 | - 'amount_of_friends' => friends_list.count, | ||
406 | - 'chat_enabled' => person.environment.enabled?('xmpp_chat') | ||
407 | - } | 388 | + self.person.data_hash(gravatar_default) |
408 | end | 389 | end |
409 | 390 | ||
410 | def self.expires_chat_status_every | 391 | def self.expires_chat_status_every |
app/views/account/welcome.html.erb
@@ -4,7 +4,7 @@ | @@ -4,7 +4,7 @@ | ||
4 | <%= _('%s was successfuly activated. Now you may go to your control panel or to the control panel of your enterprise') % @enterprise.name %> | 4 | <%= _('%s was successfuly activated. Now you may go to your control panel or to the control panel of your enterprise') % @enterprise.name %> |
5 | 5 | ||
6 | <%= button_bar do %> | 6 | <%= button_bar do %> |
7 | - <%= button 'forward', _('Go to my control panel'), :action => 'index', :controller => 'profile_editor', :profile => current_user.person.identifier %> | 7 | + <%= button 'forward', _('Go to my control panel'), :action => 'index', :controller => 'profile_editor', :profile => current_person.identifier %> |
8 | <%= button 'forward', _('Go to my enterprise control panel') % @enterprise.name, :action => 'index', :controller => 'profile_editor', :profile => @enterprise.identifier %> | 8 | <%= button 'forward', _('Go to my enterprise control panel') % @enterprise.name, :action => 'index', :controller => 'profile_editor', :profile => @enterprise.identifier %> |
9 | <% end %> | 9 | <% end %> |
10 | <% end %> | 10 | <% end %> |
app/views/enterprise_registration/basic_information.html.erb
@@ -9,7 +9,7 @@ | @@ -9,7 +9,7 @@ | ||
9 | </div> | 9 | </div> |
10 | 10 | ||
11 | <%= button_bar do %> | 11 | <%= button_bar do %> |
12 | - <%= button :back, _('Go back'), { :profile => current_user.person.identifier, :action=>"enterprises", :controller=>"profile" }%> | 12 | + <%= button :back, _('Go back'), { :profile => current_person.identifier, :action=>"enterprises", :controller=>"profile" }%> |
13 | <% end %> | 13 | <% end %> |
14 | <% else %> | 14 | <% else %> |
15 | <div class='atention'> | 15 | <div class='atention'> |
@@ -37,7 +37,7 @@ | @@ -37,7 +37,7 @@ | ||
37 | <%= template_options(:enterprises, 'create_enterprise')%> | 37 | <%= template_options(:enterprises, 'create_enterprise')%> |
38 | 38 | ||
39 | <%= button_bar do %> | 39 | <%= button_bar do %> |
40 | - <%= submit_button('next', _('Next'), :cancel => {:profile => current_user.person.identifier, :action=>"enterprises", :controller=>"profile"}) %> | 40 | + <%= submit_button('next', _('Next'), :cancel => {:profile => current_person.identifier, :action=>"enterprises", :controller=>"profile"}) %> |
41 | <% end %> | 41 | <% end %> |
42 | <% end %> | 42 | <% end %> |
43 | <% end %> | 43 | <% end %> |
app/views/environment_role_manager/affiliate.html.erb
@@ -2,7 +2,7 @@ | @@ -2,7 +2,7 @@ | ||
2 | 2 | ||
3 | <%= form_tag( {:action => 'give_role'}, {:method => :post}) do %> | 3 | <%= form_tag( {:action => 'give_role'}, {:method => :post}) do %> |
4 | <%= select_tag 'role', options_for_select(@roles.map{|r|[r.name,r.id]}) %> | 4 | <%= select_tag 'role', options_for_select(@roles.map{|r|[r.name,r.id]}) %> |
5 | - <%= hidden_field_tag 'person', current_user.person.id %> | 5 | + <%= hidden_field_tag 'person', current_person.id %> |
6 | <%= button_bar do %> | 6 | <%= button_bar do %> |
7 | <%= submit_button('affiliate', _('Affiliate', :cancel => {:action => 'index'}) %> | 7 | <%= submit_button('affiliate', _('Affiliate', :cancel => {:action => 'index'}) %> |
8 | <% end %> | 8 | <% end %> |
app/views/layouts/_user.html.erb
1 | <div id="user"> | 1 | <div id="user"> |
2 | <% user = (session[:user] && User.find_by(id: session[:user])) || nil %> | 2 | <% user = (session[:user] && User.find_by(id: session[:user])) || nil %> |
3 | + <% user ||= (session[:external] && User.new(:external_person_id => session[:external])) || nil %> | ||
3 | <% if user.present? %> | 4 | <% if user.present? %> |
4 | <% user = user.person %> | 5 | <% user = user.person %> |
5 | <span class='logged-in'> | 6 | <span class='logged-in'> |
app/views/profile_members/affiliate.html.erb
@@ -2,7 +2,7 @@ | @@ -2,7 +2,7 @@ | ||
2 | 2 | ||
3 | <%= form_tag( {:action => 'give_role'}, {:method => :post}) do %> | 3 | <%= form_tag( {:action => 'give_role'}, {:method => :post}) do %> |
4 | <%= select_tag 'role', options_for_select(@roles.map{|r|[r.name,r.id]}) %> | 4 | <%= select_tag 'role', options_for_select(@roles.map{|r|[r.name,r.id]}) %> |
5 | - <%= hidden_field_tag 'person', current_user.person.id %> | 5 | + <%= hidden_field_tag 'person', current_person.id %> |
6 | <%= button_bar do %> | 6 | <%= button_bar do %> |
7 | <%= submit_button('affiliate', _('Affiliate'), :cancel => {:action => 'index'}) %> | 7 | <%= submit_button('affiliate', _('Affiliate'), :cancel => {:action => 'index'}) %> |
8 | <% end %> | 8 | <% end %> |
config/routes.rb
@@ -87,6 +87,9 @@ Noosfero::Application.routes.draw do | @@ -87,6 +87,9 @@ Noosfero::Application.routes.draw do | ||
87 | # comments | 87 | # comments |
88 | match 'profile/:profile/comment/:action/:id', controller: 'comment', profile: /#{Noosfero.identifier_format_in_url}/i, via: :all | 88 | match 'profile/:profile/comment/:action/:id', controller: 'comment', profile: /#{Noosfero.identifier_format_in_url}/i, via: :all |
89 | 89 | ||
90 | + # icon | ||
91 | + match 'profile/:profile/icon(/:size)', controller: 'profile', action: 'icon', size: /(big|minor|thumb|portrait|icon)/, profile: /#{Noosfero.identifier_format_in_url}/i, via: :get | ||
92 | + | ||
90 | # public profile information | 93 | # public profile information |
91 | match 'profile/:profile(/:action(/:id))', controller: 'profile', action: 'index', id: /[^\/]*/, profile: /#{Noosfero.identifier_format_in_url}/i, as: :profile, via: :all | 94 | match 'profile/:profile(/:action(/:id))', controller: 'profile', action: 'index', id: /[^\/]*/, profile: /#{Noosfero.identifier_format_in_url}/i, as: :profile, via: :all |
92 | 95 |
db/migrate/20160420125236_add_type_to_polymorphic_profile_associations.rb
0 → 100644
@@ -0,0 +1,17 @@ | @@ -0,0 +1,17 @@ | ||
1 | +class AddTypeToPolymorphicProfileAssociations < ActiveRecord::Migration | ||
2 | + def up | ||
3 | + add_column :tasks, :reported_type, :string | ||
4 | + add_column :abuse_reports, :reporter_type, :string | ||
5 | + add_column :comments, :author_type, :string | ||
6 | + | ||
7 | + update("UPDATE tasks SET reported_type='Profile'") | ||
8 | + update("UPDATE abuse_reports SET reporter_type='Person'") | ||
9 | + update("UPDATE comments SET author_type='Person'") | ||
10 | + end | ||
11 | + | ||
12 | + def down | ||
13 | + remove_column :abuse_complaints, :reported_type | ||
14 | + remove_column :abuse_reports, :reporter_type | ||
15 | + remove_column :comments, :author_type | ||
16 | + end | ||
17 | +end |
@@ -0,0 +1,14 @@ | @@ -0,0 +1,14 @@ | ||
1 | +class CreateExternalPerson < ActiveRecord::Migration | ||
2 | + def change | ||
3 | + create_table :external_people do |t| | ||
4 | + t.string :name | ||
5 | + t.string :identifier | ||
6 | + t.string :source | ||
7 | + t.string :email | ||
8 | + t.integer :environment_id | ||
9 | + t.boolean :visible, default: true | ||
10 | + t.datetime :created_at | ||
11 | + t.datetime :updated_at | ||
12 | + end | ||
13 | + end | ||
14 | +end |
db/schema.rb
@@ -23,6 +23,7 @@ ActiveRecord::Schema.define(version: 20160422163123) do | @@ -23,6 +23,7 @@ ActiveRecord::Schema.define(version: 20160422163123) do | ||
23 | t.text "reason" | 23 | t.text "reason" |
24 | t.datetime "created_at" | 24 | t.datetime "created_at" |
25 | t.datetime "updated_at" | 25 | t.datetime "updated_at" |
26 | + t.string "reporter_type" | ||
26 | end | 27 | end |
27 | 28 | ||
28 | create_table "action_tracker", force: :cascade do |t| | 29 | create_table "action_tracker", force: :cascade do |t| |
@@ -289,6 +290,7 @@ ActiveRecord::Schema.define(version: 20160422163123) do | @@ -289,6 +290,7 @@ ActiveRecord::Schema.define(version: 20160422163123) do | ||
289 | t.string "user_agent" | 290 | t.string "user_agent" |
290 | t.string "referrer" | 291 | t.string "referrer" |
291 | t.text "settings" | 292 | t.text "settings" |
293 | + t.string "author_type" | ||
292 | end | 294 | end |
293 | 295 | ||
294 | add_index "comments", ["source_id", "spam"], name: "index_comments_on_source_id_and_spam", using: :btree | 296 | add_index "comments", ["source_id", "spam"], name: "index_comments_on_source_id_and_spam", using: :btree |
@@ -404,6 +406,14 @@ ActiveRecord::Schema.define(version: 20160422163123) do | @@ -404,6 +406,14 @@ ActiveRecord::Schema.define(version: 20160422163123) do | ||
404 | t.boolean "disable_feed_ssl", default: false | 406 | t.boolean "disable_feed_ssl", default: false |
405 | end | 407 | end |
406 | 408 | ||
409 | + create_table "external_environments", force: :cascade do |t| | ||
410 | + t.string "name" | ||
411 | + t.string "url" | ||
412 | + t.string "identifier" | ||
413 | + t.string "screenshot" | ||
414 | + t.string "thumbnail" | ||
415 | + end | ||
416 | + | ||
407 | create_table "external_feeds", force: :cascade do |t| | 417 | create_table "external_feeds", force: :cascade do |t| |
408 | t.string "feed_title" | 418 | t.string "feed_title" |
409 | t.datetime "fetched_at" | 419 | t.datetime "fetched_at" |
@@ -421,6 +431,17 @@ ActiveRecord::Schema.define(version: 20160422163123) do | @@ -421,6 +431,17 @@ ActiveRecord::Schema.define(version: 20160422163123) do | ||
421 | add_index "external_feeds", ["enabled"], name: "index_external_feeds_on_enabled", using: :btree | 431 | add_index "external_feeds", ["enabled"], name: "index_external_feeds_on_enabled", using: :btree |
422 | add_index "external_feeds", ["fetched_at"], name: "index_external_feeds_on_fetched_at", using: :btree | 432 | add_index "external_feeds", ["fetched_at"], name: "index_external_feeds_on_fetched_at", using: :btree |
423 | 433 | ||
434 | + create_table "external_people", force: :cascade do |t| | ||
435 | + t.string "name" | ||
436 | + t.string "identifier" | ||
437 | + t.string "source" | ||
438 | + t.string "email" | ||
439 | + t.integer "environment_id" | ||
440 | + t.boolean "visible", default: true | ||
441 | + t.datetime "created_at" | ||
442 | + t.datetime "updated_at" | ||
443 | + end | ||
444 | + | ||
424 | create_table "favorite_enterprise_people", force: :cascade do |t| | 445 | create_table "favorite_enterprise_people", force: :cascade do |t| |
425 | t.integer "person_id" | 446 | t.integer "person_id" |
426 | t.integer "enterprise_id" | 447 | t.integer "enterprise_id" |
@@ -432,14 +453,6 @@ ActiveRecord::Schema.define(version: 20160422163123) do | @@ -432,14 +453,6 @@ ActiveRecord::Schema.define(version: 20160422163123) do | ||
432 | add_index "favorite_enterprise_people", ["person_id", "enterprise_id"], name: "index_favorite_enterprise_people_on_person_id_and_enterprise_id", using: :btree | 453 | add_index "favorite_enterprise_people", ["person_id", "enterprise_id"], name: "index_favorite_enterprise_people_on_person_id_and_enterprise_id", using: :btree |
433 | add_index "favorite_enterprise_people", ["person_id"], name: "index_favorite_enterprise_people_on_person_id", using: :btree | 454 | add_index "favorite_enterprise_people", ["person_id"], name: "index_favorite_enterprise_people_on_person_id", using: :btree |
434 | 455 | ||
435 | - create_table "external_environments", force: :cascade do |t| | ||
436 | - t.string "name" | ||
437 | - t.string "url" | ||
438 | - t.string "identifier" | ||
439 | - t.string "screenshot" | ||
440 | - t.string "thumbnail" | ||
441 | - end | ||
442 | - | ||
443 | create_table "friendships", force: :cascade do |t| | 456 | create_table "friendships", force: :cascade do |t| |
444 | t.integer "person_id" | 457 | t.integer "person_id" |
445 | t.integer "friend_id" | 458 | t.integer "friend_id" |
@@ -797,6 +810,7 @@ ActiveRecord::Schema.define(version: 20160422163123) do | @@ -797,6 +810,7 @@ ActiveRecord::Schema.define(version: 20160422163123) do | ||
797 | t.boolean "spam", default: false | 810 | t.boolean "spam", default: false |
798 | t.integer "responsible_id" | 811 | t.integer "responsible_id" |
799 | t.integer "closed_by_id" | 812 | t.integer "closed_by_id" |
813 | + t.string "reported_type" | ||
800 | end | 814 | end |
801 | 815 | ||
802 | add_index "tasks", ["requestor_id"], name: "index_tasks_on_requestor_id", using: :btree | 816 | add_index "tasks", ["requestor_id"], name: "index_tasks_on_requestor_id", using: :btree |
@@ -0,0 +1,55 @@ | @@ -0,0 +1,55 @@ | ||
1 | +Feature: external login | ||
2 | + As a user | ||
3 | + I want to login using an account from a federated network | ||
4 | + In order to view pages logged in | ||
5 | + | ||
6 | + @selenium | ||
7 | + Scenario: login from portal homepage | ||
8 | + Given feature "allow_change_of_redirection_after_login" is disabled on environment | ||
9 | + And the following external environments | ||
10 | + | identifier | name | url | | ||
11 | + | test | Test | http://federated.noosfero.org | | ||
12 | + And the following external users | ||
13 | + | login | | ||
14 | + | joaosilva@federated.noosfero.org | | ||
15 | + And I am not logged in | ||
16 | + And I go to the homepage | ||
17 | + And I follow "Login" | ||
18 | + And I fill in the following: | ||
19 | + | Username / Email | joaosilva@federated.noosfero.org | | ||
20 | + | Password | 123456 | | ||
21 | + When I press "Log in" | ||
22 | + Then I should be on the homepage | ||
23 | + And I should be externally logged in as "joaosilva@federated.noosfero.org" | ||
24 | + | ||
25 | + @selenium | ||
26 | + Scenario: not login from portal homepage | ||
27 | + Given feature "allow_change_of_redirection_after_login" is disabled on environment | ||
28 | + And the following external environments | ||
29 | + | identifier | name | url | | ||
30 | + | test | Test | http://federated.noosfero.org | | ||
31 | + And I am not logged in | ||
32 | + And I go to the homepage | ||
33 | + And I follow "Login" | ||
34 | + And I fill in the following: | ||
35 | + | Username / Email | joaosilva@federated.noosfero.org | | ||
36 | + | Password | 123456 | | ||
37 | + When I press "Log in" | ||
38 | + Then I should be on /account/login | ||
39 | + And I should not be externally logged in as "joaosilva@federated.noosfero.org" | ||
40 | + | ||
41 | + @selenium | ||
42 | + Scenario: not login if network is not whitelisted | ||
43 | + Given feature "allow_change_of_redirection_after_login" is disabled on environment | ||
44 | + And the following external users | ||
45 | + | login | | ||
46 | + | joaosilva@federated.noosfero.org | | ||
47 | + And I am not logged in | ||
48 | + And I go to the homepage | ||
49 | + And I follow "Login" | ||
50 | + And I fill in the following: | ||
51 | + | Username / Email | joaosilva@federated.noosfero.org | | ||
52 | + | Password | 123456 | | ||
53 | + When I press "Log in" | ||
54 | + Then I should be on /account/login | ||
55 | + And I should not be externally logged in as "joaosilva@federated.noosfero.org" |
features/step_definitions/noosfero_steps.rb
@@ -679,3 +679,36 @@ Given /^the field (.*) is public for all users$/ do |field| | @@ -679,3 +679,36 @@ Given /^the field (.*) is public for all users$/ do |field| | ||
679 | person.save! | 679 | person.save! |
680 | end | 680 | end |
681 | end | 681 | end |
682 | + | ||
683 | +Given /^the following external users?$/ do |table| | ||
684 | + table.hashes.each do |item| | ||
685 | + person_data = item.dup | ||
686 | + username, domain = person_data['login'].split('@') | ||
687 | + response = OpenStruct.new( | ||
688 | + code: '200', | ||
689 | + body: { | ||
690 | + user: { | ||
691 | + email: username + '@ema.il', | ||
692 | + person: { | ||
693 | + identifier: username, | ||
694 | + name: username, | ||
695 | + created_at: Time.now, | ||
696 | + } | ||
697 | + } | ||
698 | + }.to_json | ||
699 | + ) | ||
700 | + Net::HTTP.stub(:post_form).and_return(response) | ||
701 | + end | ||
702 | +end | ||
703 | + | ||
704 | +Then /^I should be externally logged in as "([^@]+)@(.+)"$/ do |username, domain| | ||
705 | + visit '/' | ||
706 | + url = 'http://' + domain + '/' + username | ||
707 | + page.should have_xpath("//a[@href=\"#{url}\"]") | ||
708 | +end | ||
709 | + | ||
710 | +Then /^I should not be externally logged in as "([^@]+)@(.+)"$/ do |username, domain| | ||
711 | + visit '/' | ||
712 | + url = 'http://' + domain + '/' + username | ||
713 | + page.should_not have_xpath("//a[@href=\"#{url}\"]") | ||
714 | +end |
features/support/env.rb
@@ -8,6 +8,7 @@ ENV["RAILS_ENV"] ||= "cucumber" | @@ -8,6 +8,7 @@ ENV["RAILS_ENV"] ||= "cucumber" | ||
8 | 8 | ||
9 | require File.expand_path(File.dirname(__FILE__) + '/../../config/environment') | 9 | require File.expand_path(File.dirname(__FILE__) + '/../../config/environment') |
10 | require 'cucumber/rails' | 10 | require 'cucumber/rails' |
11 | +require 'cucumber/rspec/doubles' | ||
11 | 12 | ||
12 | Capybara.ignore_hidden_elements = true | 13 | Capybara.ignore_hidden_elements = true |
13 | 14 |
plugins/organization_ratings/controllers/organization_ratings_plugin_profile_controller.rb
@@ -38,7 +38,7 @@ class OrganizationRatingsPluginProfileController < ProfileController | @@ -38,7 +38,7 @@ class OrganizationRatingsPluginProfileController < ProfileController | ||
38 | 38 | ||
39 | def create_new_rate | 39 | def create_new_rate |
40 | @rating = OrganizationRating.new(params[:organization_rating]) | 40 | @rating = OrganizationRating.new(params[:organization_rating]) |
41 | - @rating.person = current_user.person | 41 | + @rating.person = current_person |
42 | @rating.organization = profile | 42 | @rating.organization = profile |
43 | @rating.value = params[:organization_rating_value] if params[:organization_rating_value] | 43 | @rating.value = params[:organization_rating_value] if params[:organization_rating_value] |
44 | 44 |
plugins/organization_ratings/test/functional/organization_ratings_plugin_profile_controller_test.rb
@@ -173,6 +173,7 @@ class OrganizationRatingsPluginProfileControllerTest < ActionController::TestCas | @@ -173,6 +173,7 @@ class OrganizationRatingsPluginProfileControllerTest < ActionController::TestCas | ||
173 | 173 | ||
174 | logout | 174 | logout |
175 | @controller.stubs(:logged_in?).returns(false) | 175 | @controller.stubs(:logged_in?).returns(false) |
176 | + @controller.stubs(:current_user).returns(nil) | ||
176 | 177 | ||
177 | get :new_rating, profile: @community.identifier | 178 | get :new_rating, profile: @community.identifier |
178 | assert_no_tag :tag => 'p', :content => /Report waiting for approval/, :attributes => {:class =>/comment-rejected-msg/} | 179 | assert_no_tag :tag => 'p', :content => /Report waiting for approval/, :attributes => {:class =>/comment-rejected-msg/} |
plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb
@@ -5,11 +5,11 @@ | @@ -5,11 +5,11 @@ | ||
5 | 5 | ||
6 | <div class="star-profile-information"> | 6 | <div class="star-profile-information"> |
7 | <div class="star-profile-image"> | 7 | <div class="star-profile-image"> |
8 | - <%= link_to profile_image(current_user.person, :portrait), current_user.person.url %> | 8 | + <%= link_to profile_image(current_person, :portrait), current_person.url %> |
9 | </div> | 9 | </div> |
10 | 10 | ||
11 | <div class="star-profile-name"> | 11 | <div class="star-profile-name"> |
12 | - <%= link_to current_user.person.name, current_user.person.url %> | 12 | + <%= link_to current_person.name, current_person.url %> |
13 | </div> | 13 | </div> |
14 | </div> | 14 | </div> |
15 | 15 | ||
@@ -55,14 +55,14 @@ | @@ -55,14 +55,14 @@ | ||
55 | </div> | 55 | </div> |
56 | <% elsif env_organization_ratings_config.vote_once %> | 56 | <% elsif env_organization_ratings_config.vote_once %> |
57 | <div class="star-rate-form rating-vote-once"> | 57 | <div class="star-rate-form rating-vote-once"> |
58 | - <%= _("Hi, %s! The administrators set that you can vote") % current_user.name %> | 58 | + <%= _("Hi, %s! The administrators set that you can vote") % current_person.name %> |
59 | <strong><%= _("only once") %></strong> | 59 | <strong><%= _("only once") %></strong> |
60 | <%= _("for this %s.") % profile.class.name.downcase %> | 60 | <%= _("for this %s.") % profile.class.name.downcase %> |
61 | <%= render :partial => 'shared/rating_button', :locals => { :disabled => true } %> | 61 | <%= render :partial => 'shared/rating_button', :locals => { :disabled => true } %> |
62 | </div> | 62 | </div> |
63 | <% else %> | 63 | <% else %> |
64 | <div class="star-rate-form rating-cooldown"> | 64 | <div class="star-rate-form rating-cooldown"> |
65 | - <%= _("Hi, %s! The administrators set the minimum time of") % current_user.name %> | 65 | + <%= _("Hi, %s! The administrators set the minimum time of") % current_person.name %> |
66 | <strong><%= _("%d hour(s)") % env_organization_ratings_config.cooldown %></strong> | 66 | <strong><%= _("%d hour(s)") % env_organization_ratings_config.cooldown %></strong> |
67 | <%= _("between each evaluation.") %> | 67 | <%= _("between each evaluation.") %> |
68 | 68 |
plugins/organization_ratings/views/shared/_make_report_block.html.erb
1 | -<% logged_in_image = link_to profile_image(current_user.person, :portrait), current_user.person.url if current_user %> | ||
2 | -<% logged_in_name = link_to current_user.person.name, current_user.person.url if current_user %> | ||
3 | -<% logged_out_image = image_tag('plugins/organization_ratings/images/user-not-logged.png') %> | 1 | +<% logged_in_image = link_to profile_image(current_person, :portrait), current_person.url if current_user %> |
2 | +<% logged_in_name = link_to current_person.name, current_person.url if current_user %> | ||
3 | +<% logged_out_image = image_tag('plugins/organization_ratings/public/images/user-not-logged.png') %> | ||
4 | 4 | ||
5 | <div class="make-report-block"> | 5 | <div class="make-report-block"> |
6 | <div class="star-profile-information"> | 6 | <div class="star-profile-information"> |
@@ -26,4 +26,4 @@ | @@ -26,4 +26,4 @@ | ||
26 | </div> | 26 | </div> |
27 | <% end %> | 27 | <% end %> |
28 | </div> | 28 | </div> |
29 | -</div> | ||
30 | \ No newline at end of file | 29 | \ No newline at end of file |
30 | +</div> |
plugins/responsive/lib/ext/application_helper.rb
@@ -140,7 +140,7 @@ module ApplicationHelper | @@ -140,7 +140,7 @@ module ApplicationHelper | ||
140 | [s_('contents|Most commented'), {host: host, controller: :search, action: :contents, filter: 'more_comments'}], | 140 | [s_('contents|Most commented'), {host: host, controller: :search, action: :contents, filter: 'more_comments'}], |
141 | ] | 141 | ] |
142 | if logged_in? | 142 | if logged_in? |
143 | - links.push [_('New content'), '', modal_options({href: url_for({controller: 'cms', action: 'new', profile: current_user.login, cms: true})})] | 143 | + links.push [_('New content'), '', modal_options({href: url_for({controller: 'cms', action: 'new', profile: current_person.identifier, cms: true})})] |
144 | end | 144 | end |
145 | 145 | ||
146 | content_tag :li, class: 'dropdown' do | 146 | content_tag :li, class: 'dropdown' do |
@@ -170,8 +170,8 @@ module ApplicationHelper | @@ -170,8 +170,8 @@ module ApplicationHelper | ||
170 | [s_('people|More popular'), {host: host, controller: :search, action: :people, filter: 'more_popular'}], | 170 | [s_('people|More popular'), {host: host, controller: :search, action: :people, filter: 'more_popular'}], |
171 | ] | 171 | ] |
172 | if logged_in? | 172 | if logged_in? |
173 | - links.push [_('My friends'), {profile: current_user.login, controller: 'friends'}] | ||
174 | - links.push [_('Invite friends'), {profile: current_user.login, controller: 'invite', action: 'friends'}] | 173 | + links.push [_('My friends'), {profile: current_person.identifier, controller: 'friends'}] |
174 | + links.push [_('Invite friends'), {profile: current_person.identifier, controller: 'invite', action: 'friends'}] | ||
175 | end | 175 | end |
176 | 176 | ||
177 | content_tag :li, class: 'dropdown' do | 177 | content_tag :li, class: 'dropdown' do |
@@ -201,8 +201,8 @@ module ApplicationHelper | @@ -201,8 +201,8 @@ module ApplicationHelper | ||
201 | [s_('communities|More popular'), {host: host, controller: :search, action: :communities, filter: 'more_popular'}], | 201 | [s_('communities|More popular'), {host: host, controller: :search, action: :communities, filter: 'more_popular'}], |
202 | ] | 202 | ] |
203 | if logged_in? | 203 | if logged_in? |
204 | - links.push [_('My communities'), {profile: current_user.login, controller: 'memberships'}] | ||
205 | - links.push [_('New community'), {profile: current_user.login, controller: 'memberships', action: 'new_community'}] | 204 | + links.push [_('My communities'), {profile: current_person.identifier, controller: 'memberships'}] |
205 | + links.push [_('New community'), {profile: current_person.identifier, controller: 'memberships', action: 'new_community'}] | ||
206 | end | 206 | end |
207 | 207 | ||
208 | content_tag :li, class: 'dropdown' do | 208 | content_tag :li, class: 'dropdown' do |
plugins/sniffer/views/blocks/interests.html.erb
@@ -8,7 +8,7 @@ | @@ -8,7 +8,7 @@ | ||
8 | </ul> | 8 | </ul> |
9 | 9 | ||
10 | <div> | 10 | <div> |
11 | - <% if logged_in? and (current_user.person.is_admin?(environment) or profile.admins.include?(current_user.person)) %> | 11 | + <% if logged_in? and (current_person.is_admin?(environment) or profile.admins.include?(current_person)) %> |
12 | <%= _('Edit %{inputs} and %{block.interests}') % { | 12 | <%= _('Edit %{inputs} and %{block.interests}') % { |
13 | :inputs => link_to(_("products' inputs"), :controller => :manage_products, :action => :index), | 13 | :inputs => link_to(_("products' inputs"), :controller => :manage_products, :action => :index), |
14 | :interests => link_to(_('declared interests'), :controller => :sniffer_plugin_myprofile, :action => :edit), | 14 | :interests => link_to(_('declared interests'), :controller => :sniffer_plugin_myprofile, :action => :edit), |
plugins/solr/lib/solr_plugin/search_helper.rb
@@ -12,9 +12,9 @@ module SolrPlugin::SearchHelper | @@ -12,9 +12,9 @@ module SolrPlugin::SearchHelper | ||
12 | :products => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')}, | 12 | :products => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')}, |
13 | :more_recent, {:label => c_('More recent'), :solr_opts => {:sort => 'updated_at desc, score desc'}}, | 13 | :more_recent, {:label => c_('More recent'), :solr_opts => {:sort => 'updated_at desc, score desc'}}, |
14 | :name, {:label => _('Name'), :solr_opts => {:sort => 'solr_plugin_name_sortable asc'}}, | 14 | :name, {:label => _('Name'), :solr_opts => {:sort => 'solr_plugin_name_sortable asc'}}, |
15 | - :closest, {:label => _('Closest to me'), :if => proc{ logged_in? && (profile=current_user.person).lat && profile.lng }, | 15 | + :closest, {:label => _('Closest to me'), :if => proc{ logged_in? && (profile=current_person).lat && profile.lng }, |
16 | :solr_opts => {:sort => "geodist() asc", | 16 | :solr_opts => {:sort => "geodist() asc", |
17 | - :latitude => proc{ current_user.person.lat }, :longitude => proc{ current_user.person.lng }}}, | 17 | + :latitude => proc{ current_person.lat }, :longitude => proc{ current_person.lng }}}, |
18 | ], | 18 | ], |
19 | :events => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')}, | 19 | :events => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')}, |
20 | :name, {:label => _('Name'), :solr_opts => {:sort => 'solr_plugin_name_sortable asc'}}, | 20 | :name, {:label => _('Name'), :solr_opts => {:sort => 'solr_plugin_name_sortable asc'}}, |
@@ -0,0 +1,53 @@ | @@ -0,0 +1,53 @@ | ||
1 | +require_relative '../test_helper' | ||
2 | + | ||
3 | +class WebfingerTest < ActiveSupport::TestCase | ||
4 | + def setup | ||
5 | + Domain.create(name: 'example.com') | ||
6 | + Environment.default.domains << Domain.last | ||
7 | + User.create(login: 'ze', email: 'ze@localdomain.localdomain', | ||
8 | + password: 'zeze', password_confirmation: 'zeze') | ||
9 | + end | ||
10 | + | ||
11 | + should 'return correct user via webfinger url' do | ||
12 | + get '.well-known/webfinger?resource=acct%3Aze%40example.com' | ||
13 | + webfinger = JSON.parse(last_response.body) | ||
14 | + assert_equal 200, last_response.status | ||
15 | + assert_equal webfinger['subject'], 'acct:ze@example.com' | ||
16 | + end | ||
17 | + | ||
18 | + should 'not return json when user not found' do | ||
19 | + invalid_user = 'invalid_user_in_url' | ||
20 | + get ".well-known/webfinger?resource=acct%3A#{invalid_user}%40example.com" | ||
21 | + assert_equal 404, last_response.status | ||
22 | + end | ||
23 | + | ||
24 | + should 'return correct article via webfinger url' do | ||
25 | + a = fast_create(Article, name: 'my article', profile_id: 1) | ||
26 | + get ".well-known/webfinger?resource=http://example.com/article/id/#{a.id}" | ||
27 | + webfinger = JSON.parse(last_response.body) | ||
28 | + assert_equal 200, last_response.status | ||
29 | + assert_equal webfinger['subject'], "http://example.com/article/id/#{a.id}" | ||
30 | + end | ||
31 | + | ||
32 | + should 'not return json when domain is invalid' do | ||
33 | + invalid_domain = 'doest_not_exist.com' | ||
34 | + get ".well-known/webfinger?resource=http://#{invalid_domain}/article/id/1" | ||
35 | + assert_equal 404, last_response.status | ||
36 | + end | ||
37 | + | ||
38 | + should 'not return json when entity is not found' do | ||
39 | + get '.well-known/webfinger?resource=http://example.com/article/id/999999' | ||
40 | + assert_equal 404, last_response.status | ||
41 | + end | ||
42 | + | ||
43 | + should 'not return json when entity does not exist' do | ||
44 | + get '.well-known/webfinger?resource=http://example.com/doest_not_exist/id/1' | ||
45 | + assert_equal 404, last_response.status | ||
46 | + end | ||
47 | + | ||
48 | + should 'not return json when request is not http' do | ||
49 | + not_http_url = 'kkttc://example.com/article/id/1' | ||
50 | + get ".well-known/webfinger?resource=#{not_http_url}" | ||
51 | + assert_equal 404, last_response.status | ||
52 | + end | ||
53 | +end |
test/api/people_test.rb
@@ -369,6 +369,44 @@ class PeopleTest < ActiveSupport::TestCase | @@ -369,6 +369,44 @@ class PeopleTest < ActiveSupport::TestCase | ||
369 | assert_equal "www.blog.org", json['person']['additional_data']['Custom Blog'] | 369 | assert_equal "www.blog.org", json['person']['additional_data']['Custom Blog'] |
370 | end | 370 | end |
371 | 371 | ||
372 | + should 'return portrait icon if size is not provided and there is a profile image' do | ||
373 | + img = Image.create!(uploaded_data: fixture_file_upload('/files/rails.png', 'image/png')) | ||
374 | + profile = fast_create(Person, image_id: img.id) | ||
375 | + | ||
376 | + get "/api/v1/people/#{profile.id}/icon?#{params.to_query}" | ||
377 | + assert_equal 200, last_response.status | ||
378 | + json = JSON.parse(last_response.body) | ||
379 | + assert_match(/^https?:\/\/.*portrait\.png$/, json['icon']) | ||
380 | + end | ||
381 | + | ||
382 | + should 'return icon in provided size if there is a profile image' do | ||
383 | + img = Image.create!(uploaded_data: fixture_file_upload('/files/rails.png', 'image/png')) | ||
384 | + profile = fast_create(Person, image_id: img.id) | ||
385 | + | ||
386 | + get "/api/v1/people/#{profile.id}/icon?#{params.to_query}&size=big" | ||
387 | + assert_equal 200, last_response.status | ||
388 | + json = JSON.parse(last_response.body) | ||
389 | + assert_match(/^https?:\/\/.*big\.png$/, json['icon']) | ||
390 | + end | ||
391 | + | ||
392 | + should 'return icon from gravatar without size if there is no profile image' do | ||
393 | + profile = create_user('test-user').person | ||
394 | + | ||
395 | + get "/api/v1/people/#{profile.id}/icon?#{params.to_query}" | ||
396 | + assert_equal 200, last_response.status | ||
397 | + json = JSON.parse(last_response.body) | ||
398 | + assert_match(/^https:\/\/www\.gravatar\.com.*size=64/, json['icon']) | ||
399 | + end | ||
400 | + | ||
401 | + should 'return icon from gravatar with size if there is no profile image' do | ||
402 | + profile = create_user('test-user').person | ||
403 | + | ||
404 | + get "/api/v1/people/#{profile.id}/icon?#{params.to_query}&size=big" | ||
405 | + assert_equal 200, last_response.status | ||
406 | + json = JSON.parse(last_response.body) | ||
407 | + assert_match(/^https:\/\/www\.gravatar\.com.*size=150/, json['icon']) | ||
408 | + end | ||
409 | + | ||
372 | PERSON_ATTRIBUTES = %w(vote_count comments_count articles_count following_articles_count) | 410 | PERSON_ATTRIBUTES = %w(vote_count comments_count articles_count following_articles_count) |
373 | 411 | ||
374 | PERSON_ATTRIBUTES.map do |attribute| | 412 | PERSON_ATTRIBUTES.map do |attribute| |
test/functional/comment_controller_test.rb
@@ -487,7 +487,7 @@ class CommentControllerTest < ActionController::TestCase | @@ -487,7 +487,7 @@ class CommentControllerTest < ActionController::TestCase | ||
487 | should 'edit comment from a page' do | 487 | should 'edit comment from a page' do |
488 | login_as profile.identifier | 488 | login_as profile.identifier |
489 | page = profile.articles.create!(:name => 'myarticle', :body => 'the body of the text') | 489 | page = profile.articles.create!(:name => 'myarticle', :body => 'the body of the text') |
490 | - comment = fast_create(Comment, :body => 'Original comment', :source_id => page.id, :source_type => 'Article', :author_id => profile.id) | 490 | + comment = fast_create(Comment, :body => 'Original comment', :source_id => page.id, :source_type => 'Article', :author_id => profile.id, :author_type => 'Person') |
491 | 491 | ||
492 | get :edit, :id => comment.id, :profile => profile.identifier, :comment => { :body => 'Comment edited' } | 492 | get :edit, :id => comment.id, :profile => profile.identifier, :comment => { :body => 'Comment edited' } |
493 | assert_tag :tag => 'textarea', :attributes => {:id => 'comment_body'}, :content => /Original comment/ | 493 | assert_tag :tag => 'textarea', :attributes => {:id => 'comment_body'}, :content => /Original comment/ |
@@ -522,7 +522,7 @@ class CommentControllerTest < ActionController::TestCase | @@ -522,7 +522,7 @@ class CommentControllerTest < ActionController::TestCase | ||
522 | should 'be able to update a comment' do | 522 | should 'be able to update a comment' do |
523 | login_as profile.identifier | 523 | login_as profile.identifier |
524 | page = profile.articles.create!(:name => 'myarticle', :body => 'the body of the text', :accept_comments => false) | 524 | page = profile.articles.create!(:name => 'myarticle', :body => 'the body of the text', :accept_comments => false) |
525 | - comment = fast_create(Comment, :body => 'Original comment', :source_id => page.id, :source_type => 'Article', :author_id => profile) | 525 | + comment = fast_create(Comment, :body => 'Original comment', :source_id => page.id, :source_type => 'Article', :author_id => profile, :author_type => 'Person') |
526 | 526 | ||
527 | xhr :post, :update, :id => comment.id, :profile => profile.identifier, :comment => { :body => 'Comment edited' } | 527 | xhr :post, :update, :id => comment.id, :profile => profile.identifier, :comment => { :body => 'Comment edited' } |
528 | assert ActiveSupport::JSON.decode(@response.body)["ok"], "attribute ok expected to be true" | 528 | assert ActiveSupport::JSON.decode(@response.body)["ok"], "attribute ok expected to be true" |
test/functional/profile_controller_test.rb
@@ -1932,4 +1932,37 @@ class ProfileControllerTest < ActionController::TestCase | @@ -1932,4 +1932,37 @@ class ProfileControllerTest < ActionController::TestCase | ||
1932 | assert_redirected_to :controller => 'account', :action => 'login' | 1932 | assert_redirected_to :controller => 'account', :action => 'login' |
1933 | end | 1933 | end |
1934 | 1934 | ||
1935 | + should 'return portrait icon if size is not provided and there is a profile image' do | ||
1936 | + img = Image.create!(uploaded_data: fixture_file_upload('/files/rails.png', 'image/png')) | ||
1937 | + profile = fast_create(Person, image_id: img.id) | ||
1938 | + | ||
1939 | + get :icon, profile: profile.identifier, size: nil | ||
1940 | + assert_response :success | ||
1941 | + assert_equal 'image/png', @response.header['Content-Type'] | ||
1942 | + assert File.exists?(assigns(:file)) | ||
1943 | + end | ||
1944 | + | ||
1945 | + should 'return icon in provided size if there is a profile image' do | ||
1946 | + img = Image.create!(uploaded_data: fixture_file_upload('/files/rails.png', 'image/png')) | ||
1947 | + profile = fast_create(Person, image_id: img.id) | ||
1948 | + | ||
1949 | + get :icon, profile: profile.identifier, size: :big | ||
1950 | + assert_response :success | ||
1951 | + assert_equal 'image/png', @response.header['Content-Type'] | ||
1952 | + assert File.exists?(assigns(:file)) | ||
1953 | + end | ||
1954 | + | ||
1955 | + should 'return icon from gravatar without size if there is no profile image' do | ||
1956 | + profile = fast_create(Person) | ||
1957 | + | ||
1958 | + get :icon, profile: profile.identifier | ||
1959 | + assert_redirected_to /^https:\/\/www\.gravatar\.com\/.*/ | ||
1960 | + end | ||
1961 | + | ||
1962 | + should 'return icon from gravatar with size if there is no profile image' do | ||
1963 | + profile = fast_create(Person) | ||
1964 | + | ||
1965 | + get :icon, profile: profile.identifier, size: :thumb | ||
1966 | + assert_redirected_to /^https:\/\/www\.gravatar\.com\/.*/ | ||
1967 | + end | ||
1935 | end | 1968 | end |
test/integration/routing_test.rb
@@ -276,4 +276,11 @@ class RoutingTest < ActionDispatch::IntegrationTest | @@ -276,4 +276,11 @@ class RoutingTest < ActionDispatch::IntegrationTest | ||
276 | assert_routing('/profile/~', :controller => 'profile', :profile => '~', :action => 'index') | 276 | assert_routing('/profile/~', :controller => 'profile', :profile => '~', :action => 'index') |
277 | end | 277 | end |
278 | 278 | ||
279 | + should 'have route to profile icon without size' do | ||
280 | + assert_routing('/profile/ze/icon', controller: 'profile', profile: 'ze', action: 'icon') | ||
281 | + end | ||
282 | + | ||
283 | + should 'have route to profile icon with supported size' do | ||
284 | + assert_routing('/profile/ze/icon/big', controller: 'profile', profile: 'ze', action: 'icon', size: 'big') | ||
285 | + end | ||
279 | end | 286 | end |
test/unit/comment_test.rb
@@ -23,17 +23,14 @@ class CommentTest < ActiveSupport::TestCase | @@ -23,17 +23,14 @@ class CommentTest < ActiveSupport::TestCase | ||
23 | end | 23 | end |
24 | end | 24 | end |
25 | 25 | ||
26 | - should 'record authenticated author' do | 26 | + should 'record authenticated author polymorphically' do |
27 | c = Comment.new | 27 | c = Comment.new |
28 | - assert_raise ActiveRecord::AssociationTypeMismatch do | ||
29 | - c.author = 1 | ||
30 | - end | ||
31 | - assert_raise ActiveRecord::AssociationTypeMismatch do | ||
32 | - c.author = Profile | ||
33 | - end | ||
34 | assert_nothing_raised do | 28 | assert_nothing_raised do |
35 | c.author = Person.new | 29 | c.author = Person.new |
36 | end | 30 | end |
31 | + assert_nothing_raised do | ||
32 | + c.author = ExternalPerson.new | ||
33 | + end | ||
37 | end | 34 | end |
38 | 35 | ||
39 | should 'record unauthenticated author' do | 36 | should 'record unauthenticated author' do |
@@ -0,0 +1,137 @@ | @@ -0,0 +1,137 @@ | ||
1 | +# encoding: UTF-8 | ||
2 | +require_relative "../test_helper" | ||
3 | + | ||
4 | +class ExternalPersonTest < ActiveSupport::TestCase | ||
5 | + fixtures :environments | ||
6 | + | ||
7 | + def setup | ||
8 | + @external_person = ExternalPerson.create!(identifier: 'johnlock', | ||
9 | + name: 'John Lock', | ||
10 | + source: 'anerenvironment.org', | ||
11 | + email: 'john@lock.org', | ||
12 | + created_at: Date.yesterday | ||
13 | + ) | ||
14 | + end | ||
15 | + | ||
16 | + should 'have no permissions' do | ||
17 | + assert_equivalent [], @external_person.role_assignments | ||
18 | + refute @external_person.has_permission?(:manage_friends) | ||
19 | + end | ||
20 | + | ||
21 | + should 'have no suggested profiles' do | ||
22 | + assert_equivalent [], @external_person.suggested_communities | ||
23 | + assert_equivalent [], @external_person.suggested_people | ||
24 | + assert_equivalent [], @external_person.suggested_profiles | ||
25 | + end | ||
26 | + | ||
27 | + should 'have no friendships' do | ||
28 | + refute @external_person.add_friend(fast_create(Person)) | ||
29 | + assert_equivalent [], @external_person.friendships | ||
30 | + end | ||
31 | + | ||
32 | + should 'not be a member of any communities' do | ||
33 | + community = fast_create(Community) | ||
34 | + refute community.add_member(@external_person) | ||
35 | + assert_equivalent [], @external_person.memberships | ||
36 | + end | ||
37 | + | ||
38 | + should 'not have any favorite enterprises' do | ||
39 | + assert_equivalent [], @external_person.favorite_enterprises | ||
40 | + end | ||
41 | + | ||
42 | + should 'be a person' do | ||
43 | + assert @external_person.person? | ||
44 | + end | ||
45 | + | ||
46 | + should 'not be a community, organization or enterprise' do | ||
47 | + refute @external_person.community? | ||
48 | + refute @external_person.enterprise? | ||
49 | + refute @external_person.organization? | ||
50 | + end | ||
51 | + | ||
52 | + should 'never be an admin for environments' do | ||
53 | + refute @external_person.is_admin? | ||
54 | + env = Environment.default | ||
55 | + env.add_admin @external_person | ||
56 | + refute @external_person.is_admin?(env) | ||
57 | + assert_equivalent [], env.admins | ||
58 | + end | ||
59 | + | ||
60 | + should 'redirect after login based on environment settings' do | ||
61 | + assert_respond_to ExternalPerson.new, :preferred_login_redirection | ||
62 | + environment = fast_create(Environment, :redirection_after_login => 'site_homepage') | ||
63 | + profile = fast_create(ExternalPerson, :environment_id => environment.id) | ||
64 | + assert_equal 'site_homepage', profile.preferred_login_redirection | ||
65 | + end | ||
66 | + | ||
67 | + should 'have an avatar from its original environment' do | ||
68 | + assert_match(/http:\/\/#{@external_person.source}\/.*/, @external_person.avatar) | ||
69 | + end | ||
70 | + | ||
71 | + should 'generate a custom profile icon based on its avatar' do | ||
72 | + assert_match(/http:\/\/#{@external_person.source}\/.*/, @external_person.profile_custom_icon) | ||
73 | + end | ||
74 | + | ||
75 | + should 'have an url to its profile on its original environment' do | ||
76 | + assert_match(/http:\/\/#{@external_person.source}\/profile\/.*/, @external_person.url) | ||
77 | + end | ||
78 | + | ||
79 | + should 'have a public profile url' do | ||
80 | + assert_match(/http:\/\/#{@external_person.source}\/profile\/.*/, @external_person.public_profile_url) | ||
81 | + end | ||
82 | + | ||
83 | + should 'have an admin url to its profile on its original environment' do | ||
84 | + assert_match(/http:\/\/#{@external_person.source}\/myprofile\/.*/, @external_person.admin_url) | ||
85 | + end | ||
86 | + | ||
87 | + should 'never be a friend of another person' do | ||
88 | + friend = fast_create(Person) | ||
89 | + friend.add_friend @external_person | ||
90 | + refute @external_person.is_a_friend?(friend) | ||
91 | + refute friend.is_a_friend?(@external_person) | ||
92 | + end | ||
93 | + | ||
94 | + should 'never send a friend request to another person' do | ||
95 | + friend = fast_create(Person) | ||
96 | + friend.add_friend @external_person | ||
97 | + refute friend.already_request_friendship?(@external_person) | ||
98 | + @external_person.add_friend(friend) | ||
99 | + refute @external_person.already_request_friendship?(friend) | ||
100 | + end | ||
101 | + | ||
102 | + should 'not follow another profile' do | ||
103 | + friend = fast_create(Person) | ||
104 | + friend.add_friend @external_person | ||
105 | + refute @external_person.follows?(friend) | ||
106 | + refute friend.follows?(@external_person) | ||
107 | + end | ||
108 | + | ||
109 | + should 'have an image' do | ||
110 | + assert_not_nil @external_person.image | ||
111 | + end | ||
112 | + | ||
113 | + should 'profile image has public filename and mimetype' do | ||
114 | + assert_not_nil @external_person.image.public_filename | ||
115 | + assert_not_nil @external_person.image.content_type | ||
116 | + end | ||
117 | + | ||
118 | + should 'respond to all instance methods in Profile' do | ||
119 | + methods = Profile.public_instance_methods(false) | ||
120 | + methods.each do |method| | ||
121 | + # We test if ExternalPerson responds to same methods as Profile, but we | ||
122 | + # skip methods generated by plugins, libs and validations, which are | ||
123 | + # usually only used internally | ||
124 | + assert_respond_to ExternalPerson.new, method.to_sym unless method =~ /type_name|^autosave_.*|^after_.*|^before_.*|validate_.*|^attribute_.*|.*_?tags?_?.*|^custom_value.*|^custom_context.*|^xss.*|bar/ | ||
125 | + end | ||
126 | + end | ||
127 | + | ||
128 | + should 'respond to all instance methods in Person' do | ||
129 | + methods = Person.public_instance_methods(false) | ||
130 | + methods.each do |method| | ||
131 | + # We test if ExternalPerson responds to same methods as Person, but we | ||
132 | + # skip methods generated by plugins, libs and validations, which are | ||
133 | + # usually only used internally | ||
134 | + assert_respond_to ExternalPerson.new, method.to_sym unless method =~ /^autosave_.*|validate_.*|^before_.*|^after_.*|^assignment_.*|^(city|state)_.*/ | ||
135 | + end | ||
136 | + end | ||
137 | +end |
test/unit/person_test.rb
@@ -1831,9 +1831,9 @@ class PersonTest < ActiveSupport::TestCase | @@ -1831,9 +1831,9 @@ class PersonTest < ActiveSupport::TestCase | ||
1831 | p1 = fast_create(Person) | 1831 | p1 = fast_create(Person) |
1832 | p2 = fast_create(Person) | 1832 | p2 = fast_create(Person) |
1833 | article = fast_create(Article) | 1833 | article = fast_create(Article) |
1834 | - c1 = fast_create(Comment, :source_id => article.id, :author_id => p1.id) | ||
1835 | - c2 = fast_create(Comment, :source_id => article.id, :author_id => p2.id) | ||
1836 | - c3 = fast_create(Comment, :source_id => article.id, :author_id => p1.id) | 1834 | + c1 = fast_create(Comment, :source_id => article.id, :author_id => p1.id, :author_type => 'Profile') |
1835 | + c2 = fast_create(Comment, :source_id => article.id, :author_id => p2.id, :author_type => 'Profile') | ||
1836 | + c3 = fast_create(Comment, :source_id => article.id, :author_id => p1.id, :author_type => 'Profile') | ||
1837 | 1837 | ||
1838 | assert_equivalent [c1,c3], p1.comments | 1838 | assert_equivalent [c1,c3], p1.comments |
1839 | end | 1839 | end |
test/unit/user_test.rb
@@ -759,6 +759,14 @@ class UserTest < ActiveSupport::TestCase | @@ -759,6 +759,14 @@ class UserTest < ActiveSupport::TestCase | ||
759 | end | 759 | end |
760 | end | 760 | end |
761 | 761 | ||
762 | + should 'get person or external person' do | ||
763 | + user = create_user('new_user') | ||
764 | + assert_kind_of Person, user.person | ||
765 | + user.external_person_id = ExternalPerson.create!(identifier: 'new_user', name: 'New User', email: 'newuser@usermail.com', source: 'federated.noosfero.com', created_at: Date.today).id | ||
766 | + assert_kind_of ExternalPerson, user.person | ||
767 | + assert_kind_of Person, user.person_without_external | ||
768 | + end | ||
769 | + | ||
762 | protected | 770 | protected |
763 | def new_user(options = {}) | 771 | def new_user(options = {}) |
764 | user = User.new({ :login => 'quire', :email => 'quire@example.com', :password => 'quire', :password_confirmation => 'quire' }.merge(options)) | 772 | user = User.new({ :login => 'quire', :email => 'quire@example.com', :password => 'quire', :password_confirmation => 'quire' }.merge(options)) |
vendor/plugins/noosfero_caching/init.rb
@@ -27,7 +27,7 @@ module NoosferoHttpCaching | @@ -27,7 +27,7 @@ module NoosferoHttpCaching | ||
27 | end | 27 | end |
28 | 28 | ||
29 | def noosfero_session_check | 29 | def noosfero_session_check |
30 | - headers["X-Noosfero-Auth"] = (session[:user] != nil).to_s | 30 | + headers["X-Noosfero-Auth"] = (session[:user] != nil || session[:external] != nil).to_s |
31 | end | 31 | end |
32 | 32 | ||
33 | class Middleware | 33 | class Middleware |