Commit 9cc1bb44ab99854b7fbe529b521e427b652e9a83
Exists in
staging
and in
29 other branches
Fixing conflict
Showing
219 changed files
with
2596 additions
and
6319 deletions
Show diff stats
Too many changes.
To preserve performance only 100 of 219 files displayed.
... | ... | @@ -0,0 +1,89 @@ |
1 | +require_dependency 'api/helpers' | |
2 | + | |
3 | +module Api | |
4 | + class App < Grape::API | |
5 | + use Rack::JSONP | |
6 | + | |
7 | + logger = Logger.new(File.join(Rails.root, 'log', "#{ENV['RAILS_ENV'] || 'production'}_api.log")) | |
8 | + logger.formatter = GrapeLogging::Formatters::Default.new | |
9 | + #use GrapeLogging::Middleware::RequestLogger, { logger: logger } | |
10 | + | |
11 | + rescue_from :all do |e| | |
12 | + logger.error e | |
13 | + error! e.message, 500 | |
14 | + end unless Rails.env.test? | |
15 | + | |
16 | + @@NOOSFERO_CONF = nil | |
17 | + def self.NOOSFERO_CONF | |
18 | + if @@NOOSFERO_CONF | |
19 | + @@NOOSFERO_CONF | |
20 | + else | |
21 | + file = Rails.root.join('config', 'noosfero.yml') | |
22 | + @@NOOSFERO_CONF = File.exists?(file) ? YAML.load_file(file)[Rails.env] || {} : {} | |
23 | + end | |
24 | + end | |
25 | + | |
26 | + before { set_locale } | |
27 | + before { setup_multitenancy } | |
28 | + before { detect_stuff_by_domain } | |
29 | + before { filter_disabled_plugins_endpoints } | |
30 | + before { init_noosfero_plugins } | |
31 | + after { set_session_cookie } | |
32 | + | |
33 | + version 'v1' | |
34 | + prefix [ENV['RAILS_RELATIVE_URL_ROOT'], "api"].compact.join('/') | |
35 | + format :json | |
36 | + content_type :txt, "text/plain" | |
37 | + | |
38 | + helpers Helpers | |
39 | + | |
40 | + mount V1::Session | |
41 | + mount V1::Articles | |
42 | + mount V1::Comments | |
43 | + mount V1::Users | |
44 | + mount V1::Communities | |
45 | + mount V1::People | |
46 | + mount V1::Enterprises | |
47 | + mount V1::Categories | |
48 | + mount V1::Tasks | |
49 | + mount V1::Tags | |
50 | + mount V1::Environments | |
51 | + mount V1::Search | |
52 | + mount V1::Contacts | |
53 | + mount V1::Boxes | |
54 | + mount V1::Blocks | |
55 | + mount V1::Profiles | |
56 | + mount V1::Activities | |
57 | + | |
58 | + # hook point which allow plugins to add Grape::API extensions to Api::App | |
59 | + #finds for plugins which has api mount points classes defined (the class should extends Grape::API) | |
60 | + @plugins = Noosfero::Plugin.all.map { |p| p.constantize } | |
61 | + @plugins.each do |klass| | |
62 | + if klass.public_methods.include? :api_mount_points | |
63 | + klass.api_mount_points.each do |mount_class| | |
64 | + mount mount_class if mount_class && ( mount_class < Grape::API ) | |
65 | + end | |
66 | + end | |
67 | + end | |
68 | + | |
69 | + def self.endpoint_unavailable?(endpoint, environment) | |
70 | + api_class = endpoint.options[:app] || endpoint.options[:for] | |
71 | + if api_class.present? | |
72 | + klass = api_class.name.deconstantize.constantize | |
73 | + return klass < Noosfero::Plugin && !environment.plugin_enabled?(klass) | |
74 | + end | |
75 | + end | |
76 | + | |
77 | + class << self | |
78 | + def endpoints_with_plugins(environment = nil) | |
79 | + if environment.present? | |
80 | + cloned_endpoints = endpoints_without_plugins.dup | |
81 | + cloned_endpoints.delete_if { |endpoint| endpoint_unavailable?(endpoint, environment) } | |
82 | + else | |
83 | + endpoints_without_plugins | |
84 | + end | |
85 | + end | |
86 | + alias_method_chain :endpoints, :plugins | |
87 | + end | |
88 | + end | |
89 | +end | ... | ... |
... | ... | @@ -0,0 +1,267 @@ |
1 | +module Api | |
2 | + module Entities | |
3 | + | |
4 | + Entity.format_with :timestamp do |date| | |
5 | + date.strftime('%Y/%m/%d %H:%M:%S') if date | |
6 | + end | |
7 | + | |
8 | + PERMISSIONS = { | |
9 | + :admin => 0, | |
10 | + :self => 10, | |
11 | + :private_content => 20, | |
12 | + :logged_user => 30, | |
13 | + :anonymous => 40 | |
14 | + } | |
15 | + | |
16 | + def self.can_display_profile_field? profile, options, permission_options={} | |
17 | + permissions={:field => "", :permission => :private_content} | |
18 | + permissions.merge!(permission_options) | |
19 | + field = permissions[:field] | |
20 | + permission = permissions[:permission] | |
21 | + return true if profile.public? && profile.public_fields.map{|f| f.to_sym}.include?(field.to_sym) | |
22 | + | |
23 | + current_person = options[:current_person] | |
24 | + | |
25 | + current_permission = if current_person.present? | |
26 | + if current_person.is_admin? | |
27 | + :admin | |
28 | + elsif current_person == profile | |
29 | + :self | |
30 | + elsif profile.display_private_info_to?(current_person) | |
31 | + :private_content | |
32 | + else | |
33 | + :logged_user | |
34 | + end | |
35 | + else | |
36 | + :anonymous | |
37 | + end | |
38 | + PERMISSIONS[current_permission] <= PERMISSIONS[permission] | |
39 | + end | |
40 | + | |
41 | + class Image < Entity | |
42 | + root 'images', 'image' | |
43 | + | |
44 | + expose :url do |image, options| | |
45 | + image.public_filename | |
46 | + end | |
47 | + | |
48 | + expose :icon_url do |image, options| | |
49 | + image.public_filename(:icon) | |
50 | + end | |
51 | + | |
52 | + expose :minor_url do |image, options| | |
53 | + image.public_filename(:minor) | |
54 | + end | |
55 | + | |
56 | + expose :portrait_url do |image, options| | |
57 | + image.public_filename(:portrait) | |
58 | + end | |
59 | + | |
60 | + expose :thumb_url do |image, options| | |
61 | + image.public_filename(:thumb) | |
62 | + end | |
63 | + end | |
64 | + | |
65 | + class CategoryBase < Entity | |
66 | + root 'categories', 'category' | |
67 | + expose :name, :id, :slug | |
68 | + end | |
69 | + | |
70 | + class Category < CategoryBase | |
71 | + root 'categories', 'category' | |
72 | + expose :full_name do |category, options| | |
73 | + category.full_name | |
74 | + end | |
75 | + expose :parent, :using => CategoryBase, if: { parent: true } | |
76 | + expose :children, :using => CategoryBase, if: { children: true } | |
77 | + expose :image, :using => Image | |
78 | + expose :display_color | |
79 | + end | |
80 | + | |
81 | + class Region < Category | |
82 | + root 'regions', 'region' | |
83 | + expose :parent_id | |
84 | + end | |
85 | + | |
86 | + class Block < Entity | |
87 | + root 'blocks', 'block' | |
88 | + expose :id, :type, :settings, :position, :enabled | |
89 | + expose :mirror, :mirror_block_id, :title | |
90 | + expose :api_content, if: lambda { |object, options| options[:display_api_content] || object.display_api_content_by_default? } | |
91 | + end | |
92 | + | |
93 | + class Box < Entity | |
94 | + root 'boxes', 'box' | |
95 | + expose :id, :position | |
96 | + expose :blocks, :using => Block | |
97 | + end | |
98 | + | |
99 | + class Profile < Entity | |
100 | + expose :identifier, :name, :id | |
101 | + expose :created_at, :format_with => :timestamp | |
102 | + expose :updated_at, :format_with => :timestamp | |
103 | + expose :additional_data do |profile, options| | |
104 | + hash ={} | |
105 | + profile.public_values.each do |value| | |
106 | + hash[value.custom_field.name]=value.value | |
107 | + end | |
108 | + | |
109 | + private_values = profile.custom_field_values - profile.public_values | |
110 | + private_values.each do |value| | |
111 | + if Entities.can_display_profile_field?(profile,options) | |
112 | + hash[value.custom_field.name]=value.value | |
113 | + end | |
114 | + end | |
115 | + hash | |
116 | + end | |
117 | + expose :image, :using => Image | |
118 | + expose :region, :using => Region | |
119 | + expose :type | |
120 | + expose :custom_header | |
121 | + expose :custom_footer | |
122 | + end | |
123 | + | |
124 | + class UserBasic < Entity | |
125 | + expose :id | |
126 | + expose :login | |
127 | + end | |
128 | + | |
129 | + class Person < Profile | |
130 | + root 'people', 'person' | |
131 | + expose :user, :using => UserBasic, documentation: {type: 'User', desc: 'The user data of a person' } | |
132 | + expose :vote_count | |
133 | + expose :comments_count do |person, options| | |
134 | + person.comments.count | |
135 | + end | |
136 | + expose :following_articles_count do |person, options| | |
137 | + person.following_articles.count | |
138 | + end | |
139 | + expose :articles_count do |person, options| | |
140 | + person.articles.count | |
141 | + end | |
142 | + end | |
143 | + | |
144 | + class Enterprise < Profile | |
145 | + root 'enterprises', 'enterprise' | |
146 | + end | |
147 | + | |
148 | + class Community < Profile | |
149 | + root 'communities', 'community' | |
150 | + expose :description | |
151 | + expose :admins, :if => lambda { |community, options| community.display_info_to? options[:current_person]} do |community, options| | |
152 | + community.admins.map{|admin| {"name"=>admin.name, "id"=>admin.id, "username" => admin.identifier}} | |
153 | + end | |
154 | + expose :categories, :using => Category | |
155 | + expose :members, :using => Person , :if => lambda{ |community, options| community.display_info_to? options[:current_person] } | |
156 | + end | |
157 | + | |
158 | + class CommentBase < Entity | |
159 | + expose :body, :title, :id | |
160 | + expose :created_at, :format_with => :timestamp | |
161 | + expose :author, :using => Profile | |
162 | + expose :reply_of, :using => CommentBase | |
163 | + end | |
164 | + | |
165 | + class Comment < CommentBase | |
166 | + root 'comments', 'comment' | |
167 | + expose :children, as: :replies, :using => Comment | |
168 | + end | |
169 | + | |
170 | + class ArticleBase < Entity | |
171 | + root 'articles', 'article' | |
172 | + expose :id | |
173 | + expose :body | |
174 | + expose :abstract, documentation: {type: 'String', desc: 'Teaser of the body'} | |
175 | + expose :created_at, :format_with => :timestamp | |
176 | + expose :updated_at, :format_with => :timestamp | |
177 | + expose :title, :documentation => {:type => "String", :desc => "Title of the article"} | |
178 | + expose :created_by, :as => :author, :using => Profile, :documentation => {type: 'Profile', desc: 'The profile author that create the article'} | |
179 | + expose :profile, :using => Profile, :documentation => {type: 'Profile', desc: 'The profile associated with the article'} | |
180 | + expose :categories, :using => Category | |
181 | + expose :image, :using => Image | |
182 | + expose :votes_for | |
183 | + expose :votes_against | |
184 | + expose :setting | |
185 | + expose :position | |
186 | + expose :hits | |
187 | + expose :start_date | |
188 | + expose :end_date, :documentation => {type: 'DateTime', desc: 'The date of finish of the article'} | |
189 | + expose :tag_list | |
190 | + expose :children_count | |
191 | + expose :slug, :documentation => {:type => "String", :desc => "Trimmed and parsed name of a article"} | |
192 | + expose :path | |
193 | + expose :followers_count | |
194 | + expose :votes_count | |
195 | + expose :comments_count | |
196 | + expose :archived, :documentation => {:type => "Boolean", :desc => "Defines if a article is readonly"} | |
197 | + expose :type | |
198 | + expose :comments, using: CommentBase, :if => lambda{|obj,opt| opt[:params] && ['1','true',true].include?(opt[:params][:show_comments])} | |
199 | + expose :published | |
200 | + expose :accept_comments?, as: :accept_comments | |
201 | + end | |
202 | + | |
203 | + class Article < ArticleBase | |
204 | + root 'articles', 'article' | |
205 | + expose :parent, :using => ArticleBase | |
206 | + expose :children, :using => ArticleBase do |article, options| | |
207 | + article.children.published.limit(V1::Articles::MAX_PER_PAGE) | |
208 | + end | |
209 | + end | |
210 | + | |
211 | + class User < Entity | |
212 | + root 'users', 'user' | |
213 | + | |
214 | + attrs = [:id,:login,:email,:activated?] | |
215 | + aliases = {:activated? => :activated} | |
216 | + | |
217 | + attrs.each do |attribute| | |
218 | + name = aliases.has_key?(attribute) ? aliases[attribute] : attribute | |
219 | + expose attribute, :as => name, :if => lambda{|user,options| Entities.can_display_profile_field?(user.person, options, {:field => attribute})} | |
220 | + end | |
221 | + | |
222 | + expose :person, :using => Person, :if => lambda{|user,options| user.person.display_info_to? options[:current_person]} | |
223 | + expose :permissions, :if => lambda{|user,options| Entities.can_display_profile_field?(user.person, options, {:field => :permissions, :permission => :self})} do |user, options| | |
224 | + output = {} | |
225 | + user.person.role_assignments.map do |role_assigment| | |
226 | + if role_assigment.resource.respond_to?(:identifier) && !role_assigment.role.nil? | |
227 | + output[role_assigment.resource.identifier] = role_assigment.role.permissions | |
228 | + end | |
229 | + end | |
230 | + output | |
231 | + end | |
232 | + end | |
233 | + | |
234 | + class UserLogin < User | |
235 | + root 'users', 'user' | |
236 | + expose :private_token, documentation: {type: 'String', desc: 'A valid authentication code for post/delete api actions'}, if: lambda {|object, options| object.activated? } | |
237 | + end | |
238 | + | |
239 | + class Task < Entity | |
240 | + root 'tasks', 'task' | |
241 | + expose :id | |
242 | + expose :type | |
243 | + end | |
244 | + | |
245 | + class Environment < Entity | |
246 | + expose :name | |
247 | + expose :id | |
248 | + expose :description | |
249 | + expose :settings, if: lambda { |instance, options| options[:is_admin] } | |
250 | + end | |
251 | + | |
252 | + class Tag < Entity | |
253 | + root 'tags', 'tag' | |
254 | + expose :name | |
255 | + end | |
256 | + | |
257 | + class Activity < Entity | |
258 | + root 'activities', 'activity' | |
259 | + expose :id, :params, :verb, :created_at, :updated_at, :comments_count, :visible | |
260 | + expose :user, :using => Profile | |
261 | + expose :target do |activity, opts| | |
262 | + type_map = {Profile => ::Profile, ArticleBase => ::Article}.find {|h| activity.target.kind_of?(h.last)} | |
263 | + type_map.first.represent(activity.target) unless type_map.nil? | |
264 | + end | |
265 | + end | |
266 | + end | |
267 | +end | ... | ... |
... | ... | @@ -0,0 +1,27 @@ |
1 | +module Api | |
2 | + class Entity < Grape::Entity | |
3 | + | |
4 | + def initialize(object, options = {}) | |
5 | + object = nil if object.is_a? Exception | |
6 | + super object, options | |
7 | + end | |
8 | + | |
9 | + def self.represent(objects, options = {}) | |
10 | + if options[:has_exception] | |
11 | + data = super objects, options.merge(is_inner_data: true) | |
12 | + if objects.is_a? Exception | |
13 | + data.merge ok: false, error: { | |
14 | + type: objects.class.name, | |
15 | + message: objects.message | |
16 | + } | |
17 | + else | |
18 | + data = data.serializable_hash if data.is_a? Entity | |
19 | + data.merge ok: true, error: { type: 'Success', message: '' } | |
20 | + end | |
21 | + else | |
22 | + super objects, options | |
23 | + end | |
24 | + end | |
25 | + | |
26 | + end | |
27 | +end | ... | ... |
... | ... | @@ -0,0 +1,421 @@ |
1 | +require 'base64' | |
2 | +require 'tempfile' | |
3 | + | |
4 | +module Api | |
5 | + module Helpers | |
6 | + PRIVATE_TOKEN_PARAM = :private_token | |
7 | + DEFAULT_ALLOWED_PARAMETERS = [:parent_id, :from, :until, :content_type, :author_id, :identifier, :archived] | |
8 | + | |
9 | + include SanitizeParams | |
10 | + include Noosfero::Plugin::HotSpot | |
11 | + include ForgotPasswordHelper | |
12 | + include SearchTermHelper | |
13 | + | |
14 | + def set_locale | |
15 | + I18n.locale = (params[:lang] || request.env['HTTP_ACCEPT_LANGUAGE'] || 'en') | |
16 | + end | |
17 | + | |
18 | + def init_noosfero_plugins | |
19 | + plugins | |
20 | + end | |
21 | + | |
22 | + def current_user | |
23 | + private_token = (params[PRIVATE_TOKEN_PARAM] || headers['Private-Token']).to_s | |
24 | + @current_user ||= User.find_by private_token: private_token | |
25 | + @current_user ||= plugins.dispatch("api_custom_login", request).first | |
26 | + @current_user | |
27 | + end | |
28 | + | |
29 | + def current_person | |
30 | + current_user.person unless current_user.nil? | |
31 | + end | |
32 | + | |
33 | + def is_admin?(environment) | |
34 | + return false unless current_user | |
35 | + return current_person.is_admin?(environment) | |
36 | + end | |
37 | + | |
38 | + def logout | |
39 | + @current_user = nil | |
40 | + end | |
41 | + | |
42 | + def environment | |
43 | + @environment | |
44 | + end | |
45 | + | |
46 | + def present_partial(model, options) | |
47 | + if(params[:fields].present?) | |
48 | + begin | |
49 | + fields = JSON.parse(params[:fields]) | |
50 | + if fields.present? | |
51 | + options.merge!(fields.symbolize_keys.slice(:only, :except)) | |
52 | + end | |
53 | + rescue | |
54 | + fields = params[:fields] | |
55 | + fields = fields.split(',') if fields.kind_of?(String) | |
56 | + options[:only] = Array.wrap(fields) | |
57 | + end | |
58 | + end | |
59 | + present model, options | |
60 | + end | |
61 | + | |
62 | + include FindByContents | |
63 | + | |
64 | + #################################################################### | |
65 | + #### SEARCH | |
66 | + #################################################################### | |
67 | + def multiple_search?(searches=nil) | |
68 | + ['index', 'category_index'].include?(params[:action]) || (searches && searches.size > 1) | |
69 | + end | |
70 | + #################################################################### | |
71 | + | |
72 | + def logger | |
73 | + logger = Logger.new(File.join(Rails.root, 'log', "#{ENV['RAILS_ENV'] || 'production'}_api.log")) | |
74 | + logger.formatter = GrapeLogging::Formatters::Default.new | |
75 | + logger | |
76 | + end | |
77 | + | |
78 | + def limit | |
79 | + limit = params[:limit].to_i | |
80 | + limit = default_limit if limit <= 0 | |
81 | + limit | |
82 | + end | |
83 | + | |
84 | + def period(from_date, until_date) | |
85 | + return nil if from_date.nil? && until_date.nil? | |
86 | + | |
87 | + begin_period = from_date.nil? ? Time.at(0).to_datetime : from_date | |
88 | + end_period = until_date.nil? ? DateTime.now : until_date | |
89 | + | |
90 | + begin_period..end_period | |
91 | + end | |
92 | + | |
93 | + def parse_content_type(content_type) | |
94 | + return nil if content_type.blank? | |
95 | + content_type.split(',').map do |content_type| | |
96 | + content_type.camelcase | |
97 | + end | |
98 | + end | |
99 | + | |
100 | + def find_article(articles, id) | |
101 | + article = articles.find(id) | |
102 | + article.display_to?(current_person) ? article : forbidden! | |
103 | + end | |
104 | + | |
105 | + def post_article(asset, params) | |
106 | + return forbidden! unless current_person.can_post_content?(asset) | |
107 | + | |
108 | + klass_type = params[:content_type] || params[:article].delete(:type) || TinyMceArticle.name | |
109 | + return forbidden! unless klass_type.constantize <= Article | |
110 | + | |
111 | + article = klass_type.constantize.new(params[:article]) | |
112 | + article.last_changed_by = current_person | |
113 | + article.created_by= current_person | |
114 | + article.profile = asset | |
115 | + | |
116 | + if !article.save | |
117 | + render_api_errors!(article.errors.full_messages) | |
118 | + end | |
119 | + present_partial article, :with => Entities::Article | |
120 | + end | |
121 | + | |
122 | + def present_article(asset) | |
123 | + article = find_article(asset.articles, params[:id]) | |
124 | + present_partial article, :with => Entities::Article, :params => params | |
125 | + end | |
126 | + | |
127 | + def present_articles_for_asset(asset, method = 'articles') | |
128 | + articles = find_articles(asset, method) | |
129 | + present_articles(articles) | |
130 | + end | |
131 | + | |
132 | + def present_articles(articles) | |
133 | + present_partial paginate(articles), :with => Entities::Article, :params => params | |
134 | + end | |
135 | + | |
136 | + def find_articles(asset, method = 'articles') | |
137 | + articles = select_filtered_collection_of(asset, method, params) | |
138 | + if current_person.present? | |
139 | + articles = articles.display_filter(current_person, nil) | |
140 | + else | |
141 | + articles = articles.published | |
142 | + end | |
143 | + articles | |
144 | + end | |
145 | + | |
146 | + def find_task(asset, id) | |
147 | + task = asset.tasks.find(id) | |
148 | + current_person.has_permission?(task.permission, asset) ? task : forbidden! | |
149 | + end | |
150 | + | |
151 | + def post_task(asset, params) | |
152 | + klass_type= params[:content_type].nil? ? 'Task' : params[:content_type] | |
153 | + return forbidden! unless klass_type.constantize <= Task | |
154 | + | |
155 | + task = klass_type.constantize.new(params[:task]) | |
156 | + task.requestor_id = current_person.id | |
157 | + task.target_id = asset.id | |
158 | + task.target_type = 'Profile' | |
159 | + | |
160 | + if !task.save | |
161 | + render_api_errors!(task.errors.full_messages) | |
162 | + end | |
163 | + present_partial task, :with => Entities::Task | |
164 | + end | |
165 | + | |
166 | + def present_task(asset) | |
167 | + task = find_task(asset, params[:id]) | |
168 | + present_partial task, :with => Entities::Task | |
169 | + end | |
170 | + | |
171 | + def present_tasks(asset) | |
172 | + tasks = select_filtered_collection_of(asset, 'tasks', params) | |
173 | + tasks = tasks.select {|t| current_person.has_permission?(t.permission, asset)} | |
174 | + return forbidden! if tasks.empty? && !current_person.has_permission?(:perform_task, asset) | |
175 | + present_partial tasks, :with => Entities::Task | |
176 | + end | |
177 | + | |
178 | + def make_conditions_with_parameter(params = {}) | |
179 | + parsed_params = parser_params(params) | |
180 | + conditions = {} | |
181 | + from_date = DateTime.parse(parsed_params.delete(:from)) if parsed_params[:from] | |
182 | + until_date = DateTime.parse(parsed_params.delete(:until)) if parsed_params[:until] | |
183 | + | |
184 | + conditions[:type] = parse_content_type(parsed_params.delete(:content_type)) unless parsed_params[:content_type].nil? | |
185 | + | |
186 | + conditions[:created_at] = period(from_date, until_date) if from_date || until_date | |
187 | + conditions.merge!(parsed_params) | |
188 | + | |
189 | + conditions | |
190 | + end | |
191 | + | |
192 | + # changing make_order_with_parameters to avoid sql injection | |
193 | + def make_order_with_parameters(object, method, params) | |
194 | + order = "created_at DESC" | |
195 | + unless params[:order].blank? | |
196 | + if params[:order].include? '\'' or params[:order].include? '"' | |
197 | + order = "created_at DESC" | |
198 | + elsif ['RANDOM()', 'RANDOM'].include? params[:order].upcase | |
199 | + order = 'RANDOM()' | |
200 | + else | |
201 | + field_name, direction = params[:order].split(' ') | |
202 | + assoc = object.class.reflect_on_association(method.to_sym) | |
203 | + if !field_name.blank? and assoc | |
204 | + if assoc.klass.attribute_names.include? field_name | |
205 | + if direction.present? and ['ASC','DESC'].include? direction.upcase | |
206 | + order = "#{field_name} #{direction.upcase}" | |
207 | + end | |
208 | + end | |
209 | + end | |
210 | + end | |
211 | + end | |
212 | + return order | |
213 | + end | |
214 | + | |
215 | + def make_timestamp_with_parameters_and_method(params, method) | |
216 | + timestamp = nil | |
217 | + if params[:timestamp] | |
218 | + datetime = DateTime.parse(params[:timestamp]) | |
219 | + table_name = method.to_s.singularize.camelize.constantize.table_name | |
220 | + timestamp = "#{table_name}.updated_at >= '#{datetime}'" | |
221 | + end | |
222 | + | |
223 | + timestamp | |
224 | + end | |
225 | + | |
226 | + def by_reference(scope, params) | |
227 | + reference_id = params[:reference_id].to_i == 0 ? nil : params[:reference_id].to_i | |
228 | + if reference_id.nil? | |
229 | + scope | |
230 | + else | |
231 | + created_at = scope.find(reference_id).created_at | |
232 | + scope.send("#{params.key?(:oldest) ? 'older_than' : 'younger_than'}", created_at) | |
233 | + end | |
234 | + end | |
235 | + | |
236 | + def by_categories(scope, params) | |
237 | + category_ids = params[:category_ids] | |
238 | + if category_ids.nil? | |
239 | + scope | |
240 | + else | |
241 | + scope.joins(:categories).where(:categories => {:id => category_ids}) | |
242 | + end | |
243 | + end | |
244 | + | |
245 | + def select_filtered_collection_of(object, method, params) | |
246 | + conditions = make_conditions_with_parameter(params) | |
247 | + order = make_order_with_parameters(object,method,params) | |
248 | + timestamp = make_timestamp_with_parameters_and_method(params, method) | |
249 | + | |
250 | + objects = object.send(method) | |
251 | + objects = by_reference(objects, params) | |
252 | + objects = by_categories(objects, params) | |
253 | + | |
254 | + objects = objects.where(conditions).where(timestamp).reorder(order) | |
255 | + | |
256 | + params[:page] ||= 1 | |
257 | + params[:per_page] ||= limit | |
258 | + paginate(objects) | |
259 | + end | |
260 | + | |
261 | + def authenticate! | |
262 | + unauthorized! unless current_user | |
263 | + end | |
264 | + | |
265 | + def profiles_for_person(profiles, person) | |
266 | + if person | |
267 | + profiles.listed_for_person(person) | |
268 | + else | |
269 | + profiles.visible | |
270 | + end | |
271 | + end | |
272 | + | |
273 | + # Checks the occurrences of uniqueness of attributes, each attribute must be present in the params hash | |
274 | + # or a Bad Request error is invoked. | |
275 | + # | |
276 | + # Parameters: | |
277 | + # keys (unique) - A hash consisting of keys that must be unique | |
278 | + def unique_attributes!(obj, keys) | |
279 | + keys.each do |key| | |
280 | + cant_be_saved_request!(key) if obj.find_by(key.to_s => params[key]) | |
281 | + end | |
282 | + end | |
283 | + | |
284 | + def attributes_for_keys(keys) | |
285 | + attrs = {} | |
286 | + keys.each do |key| | |
287 | + attrs[key] = params[key] if params[key].present? or (params.has_key?(key) and params[key] == false) | |
288 | + end | |
289 | + attrs | |
290 | + end | |
291 | + | |
292 | + ########################################## | |
293 | + # error helpers # | |
294 | + ########################################## | |
295 | + | |
296 | + def not_found! | |
297 | + render_api_error!('404 Not found', 404) | |
298 | + end | |
299 | + | |
300 | + def forbidden! | |
301 | + render_api_error!('403 Forbidden', 403) | |
302 | + end | |
303 | + | |
304 | + def cant_be_saved_request!(attribute) | |
305 | + message = _("(Invalid request) %s can't be saved") % attribute | |
306 | + render_api_error!(message, 400) | |
307 | + end | |
308 | + | |
309 | + def bad_request!(attribute) | |
310 | + message = _("(Invalid request) %s not given") % attribute | |
311 | + render_api_error!(message, 400) | |
312 | + end | |
313 | + | |
314 | + def something_wrong! | |
315 | + message = _("Something wrong happened") | |
316 | + render_api_error!(message, 400) | |
317 | + end | |
318 | + | |
319 | + def unauthorized! | |
320 | + render_api_error!(_('Unauthorized'), 401) | |
321 | + end | |
322 | + | |
323 | + def not_allowed! | |
324 | + render_api_error!(_('Method Not Allowed'), 405) | |
325 | + end | |
326 | + | |
327 | + # javascript_console_message is supposed to be executed as console.log() | |
328 | + def render_api_error!(user_message, status, log_message = nil, javascript_console_message = nil) | |
329 | + message_hash = {'message' => user_message, :code => status} | |
330 | + message_hash[:javascript_console_message] = javascript_console_message if javascript_console_message.present? | |
331 | + log_msg = "#{status}, User message: #{user_message}" | |
332 | + log_msg = "#{log_message}, #{log_msg}" if log_message.present? | |
333 | + log_msg = "#{log_msg}, Javascript Console Message: #{javascript_console_message}" if javascript_console_message.present? | |
334 | + logger.error log_msg unless Rails.env.test? | |
335 | + error!(message_hash, status) | |
336 | + end | |
337 | + | |
338 | + def render_api_errors!(messages) | |
339 | + messages = messages.to_a if messages.class == ActiveModel::Errors | |
340 | + render_api_error!(messages.join(','), 400) | |
341 | + end | |
342 | + | |
343 | + protected | |
344 | + | |
345 | + def set_session_cookie | |
346 | + cookies['_noosfero_api_session'] = { value: @current_user.private_token, httponly: true } if @current_user.present? | |
347 | + end | |
348 | + | |
349 | + def setup_multitenancy | |
350 | + Noosfero::MultiTenancy.setup!(request.host) | |
351 | + end | |
352 | + | |
353 | + def detect_stuff_by_domain | |
354 | + @domain = Domain.by_name(request.host) | |
355 | + if @domain.nil? | |
356 | + @environment = Environment.default | |
357 | + if @environment.nil? && Rails.env.development? | |
358 | + # This should only happen in development ... | |
359 | + @environment = Environment.create!(:name => "Noosfero", :is_default => true) | |
360 | + end | |
361 | + else | |
362 | + @environment = @domain.environment | |
363 | + end | |
364 | + end | |
365 | + | |
366 | + def filter_disabled_plugins_endpoints | |
367 | + not_found! if Api::App.endpoint_unavailable?(self, @environment) | |
368 | + end | |
369 | + | |
370 | + def asset_with_image params | |
371 | + if params.has_key? :image_builder | |
372 | + asset_api_params = params | |
373 | + asset_api_params[:image_builder] = base64_to_uploadedfile(asset_api_params[:image_builder]) | |
374 | + return asset_api_params | |
375 | + end | |
376 | + params | |
377 | + end | |
378 | + | |
379 | + def base64_to_uploadedfile(base64_image) | |
380 | + tempfile = base64_to_tempfile base64_image | |
381 | + converted_image = base64_image | |
382 | + converted_image[:tempfile] = tempfile | |
383 | + return {uploaded_data: ActionDispatch::Http::UploadedFile.new(converted_image)} | |
384 | + end | |
385 | + | |
386 | + def base64_to_tempfile base64_image | |
387 | + base64_img_str = base64_image[:tempfile] | |
388 | + decoded_base64_str = Base64.decode64(base64_img_str) | |
389 | + tempfile = Tempfile.new(base64_image[:filename]) | |
390 | + tempfile.write(decoded_base64_str.encode("ascii-8bit").force_encoding("utf-8")) | |
391 | + tempfile.rewind | |
392 | + tempfile | |
393 | + end | |
394 | + private | |
395 | + | |
396 | + def parser_params(params) | |
397 | + parsed_params = {} | |
398 | + params.map do |k,v| | |
399 | + parsed_params[k.to_sym] = v if DEFAULT_ALLOWED_PARAMETERS.include?(k.to_sym) | |
400 | + end | |
401 | + parsed_params | |
402 | + end | |
403 | + | |
404 | + def default_limit | |
405 | + 20 | |
406 | + end | |
407 | + | |
408 | + def parse_content_type(content_type) | |
409 | + return nil if content_type.blank? | |
410 | + content_type.split(',').map do |content_type| | |
411 | + content_type.camelcase | |
412 | + end | |
413 | + end | |
414 | + | |
415 | + def period(from_date, until_date) | |
416 | + begin_period = from_date.nil? ? Time.at(0).to_datetime : from_date | |
417 | + end_period = until_date.nil? ? DateTime.now : until_date | |
418 | + begin_period..end_period | |
419 | + end | |
420 | + end | |
421 | +end | ... | ... |
... | ... | @@ -0,0 +1,20 @@ |
1 | +module Api | |
2 | + module V1 | |
3 | + class Activities < Grape::API | |
4 | + before { authenticate! } | |
5 | + | |
6 | + resource :profiles do | |
7 | + | |
8 | + get ':id/activities' do | |
9 | + profile = Profile.find_by id: params[:id] | |
10 | + | |
11 | + not_found! if profile.blank? || profile.secret || !profile.visible | |
12 | + forbidden! if !profile.secret && profile.visible && !profile.display_private_info_to?(current_person) | |
13 | + | |
14 | + activities = profile.activities.map(&:activity) | |
15 | + present activities, :with => Entities::Activity, :current_person => current_person | |
16 | + end | |
17 | + end | |
18 | + end | |
19 | + end | |
20 | +end | ... | ... |
... | ... | @@ -0,0 +1,303 @@ |
1 | +module Api | |
2 | + module V1 | |
3 | + class Articles < Grape::API | |
4 | + | |
5 | + ARTICLE_TYPES = Article.descendants.map{|a| a.to_s} | |
6 | + | |
7 | + MAX_PER_PAGE = 50 | |
8 | + | |
9 | + resource :articles do | |
10 | + | |
11 | + paginate max_per_page: MAX_PER_PAGE | |
12 | + # Collect articles | |
13 | + # | |
14 | + # Parameters: | |
15 | + # from - date where the search will begin. If nothing is passed the default date will be the date of the first article created | |
16 | + # oldest - Collect the oldest articles. If nothing is passed the newest articles are collected | |
17 | + # limit - amount of articles returned. The default value is 20 | |
18 | + # | |
19 | + # Example Request: | |
20 | + # GET host/api/v1/articles?from=2013-04-04-14:41:43&until=2015-04-04-14:41:43&limit=10&private_token=e96fff37c2238fdab074d1dcea8e6317 | |
21 | + | |
22 | + desc 'Return all articles of all kinds' do | |
23 | + detail 'Get all articles filtered by fields in query params' | |
24 | + params Entities::Article.documentation | |
25 | + success Entities::Article | |
26 | + failure [[403, 'Forbidden']] | |
27 | + named 'ArticlesList' | |
28 | + headers [ | |
29 | + 'Per-Page' => { | |
30 | + description: 'Total number of records', | |
31 | + required: false | |
32 | + } | |
33 | + ] | |
34 | + end | |
35 | + get do | |
36 | + present_articles_for_asset(environment) | |
37 | + end | |
38 | + | |
39 | + desc "Return one article by id" do | |
40 | + detail 'Get only one article by id. If not found the "forbidden" http error is showed' | |
41 | + params Entities::Article.documentation | |
42 | + success Entities::Article | |
43 | + failure [[403, 'Forbidden']] | |
44 | + named 'ArticleById' | |
45 | + end | |
46 | + get ':id', requirements: {id: /[0-9]+/} do | |
47 | + present_article(environment) | |
48 | + end | |
49 | + | |
50 | + post ':id' do | |
51 | + article = environment.articles.find(params[:id]) | |
52 | + return forbidden! unless article.allow_edit?(current_person) | |
53 | + article.update_attributes!(asset_with_image(params[:article])) | |
54 | + present_partial article, :with => Entities::Article | |
55 | + end | |
56 | + | |
57 | + desc 'Report a abuse and/or violent content in a article by id' do | |
58 | + detail 'Submit a abuse (in general, a content violation) report about a specific article' | |
59 | + params Entities::Article.documentation | |
60 | + failure [[400, 'Bad Request']] | |
61 | + named 'ArticleReportAbuse' | |
62 | + end | |
63 | + post ':id/report_abuse' do | |
64 | + article = find_article(environment.articles, params[:id]) | |
65 | + profile = article.profile | |
66 | + begin | |
67 | + abuse_report = AbuseReport.new(:reason => params[:report_abuse]) | |
68 | + if !params[:content_type].blank? | |
69 | + article = params[:content_type].constantize.find(params[:content_id]) | |
70 | + abuse_report.content = article_reported_version(article) | |
71 | + end | |
72 | + | |
73 | + current_person.register_report(abuse_report, profile) | |
74 | + | |
75 | + if !params[:content_type].blank? | |
76 | + abuse_report = AbuseReport.find_by reporter_id: current_person.id, abuse_complaint_id: profile.opened_abuse_complaint.id | |
77 | + Delayed::Job.enqueue DownloadReportedImagesJob.new(abuse_report, article) | |
78 | + end | |
79 | + | |
80 | + { | |
81 | + :success => true, | |
82 | + :message => _('Your abuse report was registered. The administrators are reviewing your report.'), | |
83 | + } | |
84 | + rescue Exception => exception | |
85 | + #logger.error(exception.to_s) | |
86 | + render_api_error!(_('Your report couldn\'t be saved due to some problem. Please contact the administrator.'), 400) | |
87 | + end | |
88 | + | |
89 | + end | |
90 | + | |
91 | + desc "Returns the articles I voted" do | |
92 | + detail 'Get the Articles I make a vote' | |
93 | + failure [[403, 'Forbidden']] | |
94 | + named 'ArticleFollowers' | |
95 | + end | |
96 | + #FIXME refactor this method | |
97 | + get 'voted_by_me' do | |
98 | + present_articles(current_person.votes.where(:voteable_type => 'Article').collect(&:voteable)) | |
99 | + end | |
100 | + | |
101 | + desc 'Perform a vote on a article by id' do | |
102 | + detail 'Vote on a specific article with values: 1 (if you like) or -1 (if not)' | |
103 | + params Entities::UserLogin.documentation | |
104 | + failure [[401,'Unauthorized']] | |
105 | + named 'ArticleVote' | |
106 | + end | |
107 | + post ':id/vote' do | |
108 | + authenticate! | |
109 | + value = (params[:value] || 1).to_i | |
110 | + # FIXME verify allowed values | |
111 | + render_api_error!('Vote value not allowed', 400) unless [-1, 1].include?(value) | |
112 | + article = find_article(environment.articles, params[:id]) | |
113 | + begin | |
114 | + vote = Vote.new(:voteable => article, :voter => current_person, :vote => value) | |
115 | + {:vote => vote.save!} | |
116 | + rescue ActiveRecord::RecordInvalid => e | |
117 | + render_api_error!(e.message, 400) | |
118 | + end | |
119 | + end | |
120 | + | |
121 | + desc "Returns the total followers for the article" do | |
122 | + detail 'Get the followers of a specific article by id' | |
123 | + failure [[403, 'Forbidden']] | |
124 | + named 'ArticleFollowers' | |
125 | + end | |
126 | + get ':id/followers' do | |
127 | + article = find_article(environment.articles, params[:id]) | |
128 | + total = article.person_followers.count | |
129 | + {:total_followers => total} | |
130 | + end | |
131 | + | |
132 | + desc "Return the articles followed by me" | |
133 | + get 'followed_by_me' do | |
134 | + present_articles_for_asset(current_person, 'following_articles') | |
135 | + end | |
136 | + | |
137 | + desc "Add a follower for the article" do | |
138 | + detail 'Add the current user identified by private token, like a follower of a article' | |
139 | + params Entities::UserLogin.documentation | |
140 | + failure [[401, 'Unauthorized']] | |
141 | + named 'ArticleFollow' | |
142 | + end | |
143 | + post ':id/follow' do | |
144 | + authenticate! | |
145 | + article = find_article(environment.articles, params[:id]) | |
146 | + if article.article_followers.exists?(:person_id => current_person.id) | |
147 | + {:success => false, :already_follow => true} | |
148 | + else | |
149 | + article_follower = ArticleFollower.new | |
150 | + article_follower.article = article | |
151 | + article_follower.person = current_person | |
152 | + article_follower.save! | |
153 | + {:success => true} | |
154 | + end | |
155 | + end | |
156 | + | |
157 | + desc 'Return the children of a article identified by id' do | |
158 | + detail 'Get all children articles of a specific article' | |
159 | + params Entities::Article.documentation | |
160 | + failure [[403, 'Forbidden']] | |
161 | + named 'ArticleChildren' | |
162 | + end | |
163 | + | |
164 | + paginate per_page: MAX_PER_PAGE, max_per_page: MAX_PER_PAGE | |
165 | + get ':id/children' do | |
166 | + article = find_article(environment.articles, params[:id]) | |
167 | + | |
168 | + #TODO make tests for this situation | |
169 | + votes_order = params.delete(:order) if params[:order]=='votes_score' | |
170 | + articles = select_filtered_collection_of(article, 'children', params) | |
171 | + articles = articles.display_filter(current_person, article.profile) | |
172 | + | |
173 | + #TODO make tests for this situation | |
174 | + if votes_order | |
175 | + articles = articles.joins('left join votes on articles.id=votes.voteable_id').group('articles.id').reorder('sum(coalesce(votes.vote, 0)) DESC') | |
176 | + end | |
177 | + Article.hit(articles) | |
178 | + present_articles(articles) | |
179 | + end | |
180 | + | |
181 | + desc 'Return one child of a article identified by id' do | |
182 | + detail 'Get a child of a specific article' | |
183 | + params Entities::Article.documentation | |
184 | + success Entities::Article | |
185 | + failure [[403, 'Forbidden']] | |
186 | + named 'ArticleChild' | |
187 | + end | |
188 | + get ':id/children/:child_id' do | |
189 | + article = find_article(environment.articles, params[:id]) | |
190 | + child = find_article(article.children, params[:child_id]) | |
191 | + child.hit | |
192 | + present_partial child, :with => Entities::Article | |
193 | + end | |
194 | + | |
195 | + desc 'Suggest a article to another profile' do | |
196 | + detail 'Suggest a article to another profile (person, community...)' | |
197 | + params Entities::Article.documentation | |
198 | + success Entities::Task | |
199 | + failure [[401,'Unauthorized']] | |
200 | + named 'ArticleSuggest' | |
201 | + end | |
202 | + post ':id/children/suggest' do | |
203 | + authenticate! | |
204 | + parent_article = environment.articles.find(params[:id]) | |
205 | + | |
206 | + suggest_article = SuggestArticle.new | |
207 | + suggest_article.article = params[:article] | |
208 | + suggest_article.article[:parent_id] = parent_article.id | |
209 | + suggest_article.target = parent_article.profile | |
210 | + suggest_article.requestor = current_person | |
211 | + | |
212 | + unless suggest_article.save | |
213 | + render_api_errors!(suggest_article.article_object.errors.full_messages) | |
214 | + end | |
215 | + present_partial suggest_article, :with => Entities::Task | |
216 | + end | |
217 | + | |
218 | + # Example Request: | |
219 | + # POST api/v1/articles/:id/children?private_token=234298743290432&article[name]=title&article[body]=body | |
220 | + desc 'Add a child article to a parent identified by id' do | |
221 | + detail 'Create a new article and associate to a parent' | |
222 | + params Entities::Article.documentation | |
223 | + success Entities::Article | |
224 | + failure [[401,'Unauthorized']] | |
225 | + named 'ArticleAddChild' | |
226 | + end | |
227 | + post ':id/children' do | |
228 | + parent_article = environment.articles.find(params[:id]) | |
229 | + params[:article][:parent_id] = parent_article.id | |
230 | + post_article(parent_article.profile, params) | |
231 | + end | |
232 | + end | |
233 | + | |
234 | + resource :profiles do | |
235 | + get ':id/home_page' do | |
236 | + profiles = environment.profiles | |
237 | + profiles = profiles.visible_for_person(current_person) | |
238 | + profile = profiles.find_by id: params[:id] | |
239 | + present_partial profile.home_page, :with => Entities::Article | |
240 | + end | |
241 | + end | |
242 | + | |
243 | + kinds = %w[profile community person enterprise] | |
244 | + kinds.each do |kind| | |
245 | + resource kind.pluralize.to_sym do | |
246 | + segment "/:#{kind}_id" do | |
247 | + resource :articles do | |
248 | + | |
249 | + desc "Return all articles associate with a profile of type #{kind}" do | |
250 | + detail 'Get a list of articles of a profile' | |
251 | + params Entities::Article.documentation | |
252 | + success Entities::Article | |
253 | + failure [[403, 'Forbidden']] | |
254 | + named 'ArticlesOfProfile' | |
255 | + end | |
256 | + get do | |
257 | + profile = environment.send(kind.pluralize).find(params["#{kind}_id"]) | |
258 | + | |
259 | + if params[:path].present? | |
260 | + article = profile.articles.find_by path: params[:path] | |
261 | + if !article || !article.display_to?(current_person) | |
262 | + article = forbidden! | |
263 | + end | |
264 | + | |
265 | + present_partial article, :with => Entities::Article | |
266 | + else | |
267 | + | |
268 | + present_articles_for_asset(profile) | |
269 | + end | |
270 | + end | |
271 | + | |
272 | + desc "Return a article associate with a profile of type #{kind}" do | |
273 | + detail 'Get only one article of a profile' | |
274 | + params Entities::Article.documentation | |
275 | + success Entities::Article | |
276 | + failure [[403, 'Forbidden']] | |
277 | + named 'ArticleOfProfile' | |
278 | + end | |
279 | + get ':id' do | |
280 | + profile = environment.send(kind.pluralize).find(params["#{kind}_id"]) | |
281 | + present_article(profile) | |
282 | + end | |
283 | + | |
284 | + # Example Request: | |
285 | + # POST api/v1/{people,communities,enterprises}/:asset_id/articles?private_token=234298743290432&article[name]=title&article[body]=body | |
286 | + desc "Add a new article associated with a profile of type #{kind}" do | |
287 | + detail 'Create a new article and associate with a profile' | |
288 | + params Entities::Article.documentation | |
289 | + success Entities::Article | |
290 | + failure [[403, 'Forbidden']] | |
291 | + named 'ArticleCreateToProfile' | |
292 | + end | |
293 | + post do | |
294 | + profile = environment.send(kind.pluralize).find(params["#{kind}_id"]) | |
295 | + post_article(profile, params) | |
296 | + end | |
297 | + end | |
298 | + end | |
299 | + end | |
300 | + end | |
301 | + end | |
302 | + end | |
303 | +end | ... | ... |
... | ... | @@ -0,0 +1,15 @@ |
1 | +module Api | |
2 | + module V1 | |
3 | + | |
4 | + class Blocks < Grape::API | |
5 | + resource :blocks do | |
6 | + get ':id' do | |
7 | + block = Block.find(params["id"]) | |
8 | + return forbidden! unless block.visible_to_user?(current_person) | |
9 | + present block, :with => Entities::Block, display_api_content: true | |
10 | + end | |
11 | + end | |
12 | + end | |
13 | + | |
14 | + end | |
15 | +end | ... | ... |
... | ... | @@ -0,0 +1,44 @@ |
1 | +module Api | |
2 | + module V1 | |
3 | + | |
4 | + class Boxes < Grape::API | |
5 | + | |
6 | + kinds = %w[profile community person enterprise] | |
7 | + kinds.each do |kind| | |
8 | + | |
9 | + resource kind.pluralize.to_sym do | |
10 | + | |
11 | + segment "/:#{kind}_id" do | |
12 | + resource :boxes do | |
13 | + get do | |
14 | + profile = environment.send(kind.pluralize).find(params["#{kind}_id"]) | |
15 | + present profile.boxes, :with => Entities::Box | |
16 | + end | |
17 | + end | |
18 | + end | |
19 | + end | |
20 | + | |
21 | + end | |
22 | + | |
23 | + resource :environments do | |
24 | + [ '/default', '/context', ':environment_id' ].each do |route| | |
25 | + segment route do | |
26 | + resource :boxes do | |
27 | + get do | |
28 | + if (route.match(/default/)) | |
29 | + env = Environment.default | |
30 | + elsif (route.match(/context/)) | |
31 | + env = environment | |
32 | + else | |
33 | + env = Environment.find(params[:environment_id]) | |
34 | + end | |
35 | + present env.boxes, :with => Entities::Box | |
36 | + end | |
37 | + end | |
38 | + end | |
39 | + end | |
40 | + end | |
41 | + end | |
42 | + | |
43 | + end | |
44 | +end | ... | ... |
... | ... | @@ -0,0 +1,25 @@ |
1 | +module Api | |
2 | + module V1 | |
3 | + class Categories < Grape::API | |
4 | + | |
5 | + resource :categories do | |
6 | + | |
7 | + get do | |
8 | + type = params[:category_type] | |
9 | + include_parent = params[:include_parent] == 'true' | |
10 | + include_children = params[:include_children] == 'true' | |
11 | + | |
12 | + categories = type.nil? ? environment.categories : environment.categories.where(:type => type) | |
13 | + present categories, :with => Entities::Category, parent: include_parent, children: include_children | |
14 | + end | |
15 | + | |
16 | + desc "Return the category by id" | |
17 | + get ':id' do | |
18 | + present environment.categories.find(params[:id]), :with => Entities::Category, parent: true, children: true | |
19 | + end | |
20 | + | |
21 | + end | |
22 | + | |
23 | + end | |
24 | + end | |
25 | +end | ... | ... |
... | ... | @@ -0,0 +1,49 @@ |
1 | +module Api | |
2 | + module V1 | |
3 | + class Comments < Grape::API | |
4 | + MAX_PER_PAGE = 20 | |
5 | + | |
6 | + | |
7 | + resource :articles do | |
8 | + paginate max_per_page: MAX_PER_PAGE | |
9 | + # Collect comments from articles | |
10 | + # | |
11 | + # Parameters: | |
12 | + # reference_id - comment id used as reference to collect comment | |
13 | + # oldest - Collect the oldest comments from reference_id comment. If nothing is passed the newest comments are collected | |
14 | + # limit - amount of comments returned. The default value is 20 | |
15 | + # | |
16 | + # Example Request: | |
17 | + # GET /articles/12/comments?oldest&limit=10&reference_id=23 | |
18 | + get ":id/comments" do | |
19 | + article = find_article(environment.articles, params[:id]) | |
20 | + comments = select_filtered_collection_of(article, :comments, params) | |
21 | + comments = comments.without_spam | |
22 | + comments = comments.without_reply if(params[:without_reply].present?) | |
23 | + comments = plugins.filter(:unavailable_comments, comments) | |
24 | + present paginate(comments), :with => Entities::Comment, :current_person => current_person | |
25 | + end | |
26 | + | |
27 | + get ":id/comments/:comment_id" do | |
28 | + article = find_article(environment.articles, params[:id]) | |
29 | + present article.comments.find(params[:comment_id]), :with => Entities::Comment, :current_person => current_person | |
30 | + end | |
31 | + | |
32 | + # Example Request: | |
33 | + # POST api/v1/articles/12/comments?private_token=2298743290432&body=new comment&title=New | |
34 | + post ":id/comments" do | |
35 | + authenticate! | |
36 | + article = find_article(environment.articles, params[:id]) | |
37 | + options = params.select { |key,v| !['id','private_token'].include?(key) }.merge(:author => current_person, :source => article) | |
38 | + begin | |
39 | + comment = Comment.create!(options) | |
40 | + rescue ActiveRecord::RecordInvalid => e | |
41 | + render_api_error!(e.message, 400) | |
42 | + end | |
43 | + present comment, :with => Entities::Comment, :current_person => current_person | |
44 | + end | |
45 | + end | |
46 | + | |
47 | + end | |
48 | + end | |
49 | +end | ... | ... |
... | ... | @@ -0,0 +1,82 @@ |
1 | +module Api | |
2 | + module V1 | |
3 | + class Communities < Grape::API | |
4 | + | |
5 | + resource :communities do | |
6 | + | |
7 | + # Collect comments from articles | |
8 | + # | |
9 | + # Parameters: | |
10 | + # from - date where the search will begin. If nothing is passed the default date will be the date of the first article created | |
11 | + # oldest - Collect the oldest comments from reference_id comment. If nothing is passed the newest comments are collected | |
12 | + # limit - amount of comments returned. The default value is 20 | |
13 | + # | |
14 | + # Example Request: | |
15 | + # GET /communities?from=2013-04-04-14:41:43&until=2014-04-04-14:41:43&limit=10 | |
16 | + # GET /communities?reference_id=10&limit=10&oldest | |
17 | + get do | |
18 | + communities = select_filtered_collection_of(environment, 'communities', params) | |
19 | + communities = profiles_for_person(communities, current_person) | |
20 | + communities = communities.by_location(params) # Must be the last. May return Exception obj | |
21 | + present communities, :with => Entities::Community, :current_person => current_person | |
22 | + end | |
23 | + | |
24 | + | |
25 | + # Example Request: | |
26 | + # POST api/v1/communties?private_token=234298743290432&community[name]=some_name | |
27 | + # for each custom field for community, add &community[field_name]=field_value to the request | |
28 | + post do | |
29 | + authenticate! | |
30 | + params[:community] ||= {} | |
31 | + | |
32 | + params[:community][:custom_values]={} | |
33 | + params[:community].keys.each do |key| | |
34 | + params[:community][:custom_values][key]=params[:community].delete(key) if Community.custom_fields(environment).any?{|cf| cf.name==key} | |
35 | + end | |
36 | + | |
37 | + begin | |
38 | + community = Community.create_after_moderation(current_person, params[:community].merge({:environment => environment})) | |
39 | + rescue | |
40 | + community = Community.new(params[:community]) | |
41 | + end | |
42 | + | |
43 | + if !community.save | |
44 | + render_api_errors!(community.errors.full_messages) | |
45 | + end | |
46 | + | |
47 | + present community, :with => Entities::Community, :current_person => current_person | |
48 | + end | |
49 | + | |
50 | + get ':id' do | |
51 | + community = profiles_for_person(environment.communities, current_person).find_by_id(params[:id]) | |
52 | + present community, :with => Entities::Community, :current_person => current_person | |
53 | + end | |
54 | + | |
55 | + end | |
56 | + | |
57 | + resource :people do | |
58 | + | |
59 | + segment '/:person_id' do | |
60 | + | |
61 | + resource :communities do | |
62 | + | |
63 | + get do | |
64 | + person = environment.people.find(params[:person_id]) | |
65 | + | |
66 | + not_found! if person.blank? | |
67 | + forbidden! if !person.display_info_to?(current_person) | |
68 | + | |
69 | + communities = select_filtered_collection_of(person, 'communities', params) | |
70 | + communities = communities.visible | |
71 | + present communities, :with => Entities::Community, :current_person => current_person | |
72 | + end | |
73 | + | |
74 | + end | |
75 | + | |
76 | + end | |
77 | + | |
78 | + end | |
79 | + | |
80 | + end | |
81 | + end | |
82 | +end | ... | ... |
... | ... | @@ -0,0 +1,26 @@ |
1 | +module Api | |
2 | + module V1 | |
3 | + class Contacts < Grape::API | |
4 | + | |
5 | + resource :communities do | |
6 | + | |
7 | + resource ':id/contact' do | |
8 | + #contact => {:name => 'some name', :email => 'test@mail.com', :subject => 'some title', :message => 'some message'} | |
9 | + desc "Send a contact message" | |
10 | + post do | |
11 | + profile = environment.communities.find(params[:id]) | |
12 | + forbidden! unless profile.present? | |
13 | + contact = Contact.new params[:contact].merge(dest: profile) | |
14 | + if contact.deliver | |
15 | + {:success => true} | |
16 | + else | |
17 | + {:success => false} | |
18 | + end | |
19 | + end | |
20 | + | |
21 | + end | |
22 | + end | |
23 | + | |
24 | + end | |
25 | + end | |
26 | +end | ... | ... |
... | ... | @@ -0,0 +1,55 @@ |
1 | +module Api | |
2 | + module V1 | |
3 | + class Enterprises < Grape::API | |
4 | + | |
5 | + resource :enterprises do | |
6 | + | |
7 | + # Collect enterprises from environment | |
8 | + # | |
9 | + # Parameters: | |
10 | + # from - date where the search will begin. If nothing is passed the default date will be the date of the first article created | |
11 | + # oldest - Collect the oldest comments from reference_id comment. If nothing is passed the newest comments are collected | |
12 | + # limit - amount of comments returned. The default value is 20 | |
13 | + # georef params - read `Profile.by_location` for more information. | |
14 | + # | |
15 | + # Example Request: | |
16 | + # GET /enterprises?from=2013-04-04-14:41:43&until=2014-04-04-14:41:43&limit=10 | |
17 | + # GET /enterprises?reference_id=10&limit=10&oldest | |
18 | + get do | |
19 | + enterprises = select_filtered_collection_of(environment, 'enterprises', params) | |
20 | + enterprises = enterprises.visible | |
21 | + enterprises = enterprises.by_location(params) # Must be the last. May return Exception obj. | |
22 | + present enterprises, :with => Entities::Enterprise, :current_person => current_person | |
23 | + end | |
24 | + | |
25 | + desc "Return one enterprise by id" | |
26 | + get ':id' do | |
27 | + enterprise = environment.enterprises.visible.find_by(id: params[:id]) | |
28 | + present enterprise, :with => Entities::Enterprise, :current_person => current_person | |
29 | + end | |
30 | + | |
31 | + end | |
32 | + | |
33 | + resource :people do | |
34 | + | |
35 | + segment '/:person_id' do | |
36 | + | |
37 | + resource :enterprises do | |
38 | + | |
39 | + get do | |
40 | + person = environment.people.find(params[:person_id]) | |
41 | + enterprises = select_filtered_collection_of(person, 'enterprises', params) | |
42 | + enterprises = enterprises.visible.by_location(params) | |
43 | + present enterprises, :with => Entities::Enterprise, :current_person => current_person | |
44 | + end | |
45 | + | |
46 | + end | |
47 | + | |
48 | + end | |
49 | + | |
50 | + end | |
51 | + | |
52 | + | |
53 | + end | |
54 | + end | |
55 | +end | ... | ... |
... | ... | @@ -0,0 +1,28 @@ |
1 | +module Api | |
2 | + module V1 | |
3 | + class Environments < Grape::API | |
4 | + | |
5 | + resource :environment do | |
6 | + | |
7 | + desc "Return the person information" | |
8 | + get '/signup_person_fields' do | |
9 | + present environment.signup_person_fields | |
10 | + end | |
11 | + | |
12 | + get ':id' do | |
13 | + local_environment = nil | |
14 | + if (params[:id] == "default") | |
15 | + local_environment = Environment.default | |
16 | + elsif (params[:id] == "context") | |
17 | + local_environment = environment | |
18 | + else | |
19 | + local_environment = Environment.find(params[:id]) | |
20 | + end | |
21 | + present_partial local_environment, :with => Entities::Environment, :is_admin => is_admin?(local_environment) | |
22 | + end | |
23 | + | |
24 | + end | |
25 | + | |
26 | + end | |
27 | + end | |
28 | +end | ... | ... |
... | ... | @@ -0,0 +1,127 @@ |
1 | +module Api | |
2 | + module V1 | |
3 | + class People < Grape::API | |
4 | + | |
5 | + MAX_PER_PAGE = 50 | |
6 | + | |
7 | + desc 'API Root' | |
8 | + | |
9 | + resource :people do | |
10 | + paginate max_per_page: MAX_PER_PAGE | |
11 | + | |
12 | + # -- A note about privacy -- | |
13 | + # We wold find people by location, but we must test if the related | |
14 | + # fields are public. We can't do it now, with SQL, while the location | |
15 | + # data and the fields_privacy are a serialized settings. | |
16 | + # We must build a new table for profile data, where we can set meta-data | |
17 | + # like: | |
18 | + # | id | profile_id | key | value | privacy_level | source | | |
19 | + # | 1 | 99 | city | Salvador | friends | user | | |
20 | + # | 2 | 99 | lng | -38.521 | me only | automatic | | |
21 | + | |
22 | + # Collect people from environment | |
23 | + # | |
24 | + # Parameters: | |
25 | + # from - date where the search will begin. If nothing is passed the default date will be the date of the first article created | |
26 | + # oldest - Collect the oldest comments from reference_id comment. If nothing is passed the newest comments are collected | |
27 | + # limit - amount of comments returned. The default value is 20 | |
28 | + # | |
29 | + # Example Request: | |
30 | + # GET /people?from=2013-04-04-14:41:43&until=2014-04-04-14:41:43&limit=10 | |
31 | + # GET /people?reference_id=10&limit=10&oldest | |
32 | + | |
33 | + desc "Find environment's people" | |
34 | + get do | |
35 | + people = select_filtered_collection_of(environment, 'people', params) | |
36 | + people = people.visible | |
37 | + present_partial people, :with => Entities::Person, :current_person => current_person | |
38 | + end | |
39 | + | |
40 | + desc "Return the logged user information" | |
41 | + get "/me" do | |
42 | + authenticate! | |
43 | + present_partial current_person, :with => Entities::Person, :current_person => current_person | |
44 | + end | |
45 | + | |
46 | + desc "Return the person information" | |
47 | + get ':id' do | |
48 | + person = environment.people.visible.find_by(id: params[:id]) | |
49 | + return not_found! if person.blank? | |
50 | + present person, :with => Entities::Person, :current_person => current_person | |
51 | + end | |
52 | + | |
53 | + desc "Update person information" | |
54 | + post ':id' do | |
55 | + authenticate! | |
56 | + return forbidden! if current_person.id.to_s != params[:id] | |
57 | + current_person.update_attributes!(asset_with_image(params[:person])) | |
58 | + present current_person, :with => Entities::Person, :current_person => current_person | |
59 | + end | |
60 | + | |
61 | + # POST api/v1/people?person[login]=some_login&person[password]=some_password&person[name]=Jack | |
62 | + # for each custom field for person, add &person[field_name]=field_value to the request | |
63 | + desc "Create person" | |
64 | + post do | |
65 | + authenticate! | |
66 | + user_data = {} | |
67 | + user_data[:login] = params[:person].delete(:login) || params[:person][:identifier] | |
68 | + user_data[:email] = params[:person].delete(:email) | |
69 | + user_data[:password] = params[:person].delete(:password) | |
70 | + user_data[:password_confirmation] = params[:person].delete(:password_confirmation) | |
71 | + | |
72 | + params[:person][:custom_values]={} | |
73 | + params[:person].keys.each do |key| | |
74 | + params[:person][:custom_values][key]=params[:person].delete(key) if Person.custom_fields(environment).any?{|cf| cf.name==key} | |
75 | + end | |
76 | + | |
77 | + user = User.build(user_data, asset_with_image(params[:person]), environment) | |
78 | + | |
79 | + begin | |
80 | + user.signup! | |
81 | + rescue ActiveRecord::RecordInvalid | |
82 | + render_api_errors!(user.errors.full_messages) | |
83 | + end | |
84 | + | |
85 | + present user.person, :with => Entities::Person, :current_person => user.person | |
86 | + end | |
87 | + | |
88 | + desc "Return the person friends" | |
89 | + get ':id/friends' do | |
90 | + person = environment.people.visible.find_by(id: params[:id]) | |
91 | + return not_found! if person.blank? | |
92 | + friends = person.friends.visible | |
93 | + present friends, :with => Entities::Person, :current_person => current_person | |
94 | + end | |
95 | + | |
96 | + desc "Return the person permissions on other profiles" | |
97 | + get ":id/permissions" do | |
98 | + authenticate! | |
99 | + person = environment.people.find(params[:id]) | |
100 | + return not_found! if person.blank? | |
101 | + return forbidden! unless current_person == person || environment.admins.include?(current_person) | |
102 | + | |
103 | + output = {} | |
104 | + person.role_assignments.map do |role_assigment| | |
105 | + if role_assigment.resource.respond_to?(:identifier) | |
106 | + output[role_assigment.resource.identifier] = role_assigment.role.permissions | |
107 | + end | |
108 | + end | |
109 | + present output | |
110 | + end | |
111 | + end | |
112 | + | |
113 | + resource :profiles do | |
114 | + segment '/:profile_id' do | |
115 | + resource :members do | |
116 | + paginate max_per_page: MAX_PER_PAGE | |
117 | + get do | |
118 | + profile = environment.profiles.find_by id: params[:profile_id] | |
119 | + members = select_filtered_collection_of(profile, 'members', params) | |
120 | + present members, :with => Entities::Person, :current_person => current_person | |
121 | + end | |
122 | + end | |
123 | + end | |
124 | + end | |
125 | + end | |
126 | + end | |
127 | +end | ... | ... |
... | ... | @@ -0,0 +1,42 @@ |
1 | +module Api | |
2 | + module V1 | |
3 | + class Profiles < Grape::API | |
4 | + | |
5 | + resource :profiles do | |
6 | + | |
7 | + get do | |
8 | + profiles = select_filtered_collection_of(environment, 'profiles', params) | |
9 | + profiles = profiles.visible | |
10 | + profiles = profiles.by_location(params) # Must be the last. May return Exception obj. | |
11 | + present profiles, :with => Entities::Profile, :current_person => current_person | |
12 | + end | |
13 | + | |
14 | + get ':id' do | |
15 | + profiles = environment.profiles | |
16 | + profiles = profiles.visible | |
17 | + profile = profiles.find_by id: params[:id] | |
18 | + | |
19 | + if profile | |
20 | + present profile, :with => Entities::Profile, :current_person => current_person | |
21 | + else | |
22 | + not_found! | |
23 | + end | |
24 | + end | |
25 | + | |
26 | + delete ':id' do | |
27 | + authenticate! | |
28 | + profiles = environment.profiles | |
29 | + profile = profiles.find_by id: params[:id] | |
30 | + | |
31 | + not_found! if profile.blank? | |
32 | + | |
33 | + if current_person.has_permission?(:destroy_profile, profile) | |
34 | + profile.destroy | |
35 | + else | |
36 | + forbidden! | |
37 | + end | |
38 | + end | |
39 | + end | |
40 | + end | |
41 | + end | |
42 | +end | ... | ... |
... | ... | @@ -0,0 +1,37 @@ |
1 | +module Api | |
2 | + module V1 | |
3 | + class Search < Grape::API | |
4 | + | |
5 | + resource :search do | |
6 | + resource :article do | |
7 | + paginate max_per_page: 200 | |
8 | + get do | |
9 | + # Security checks | |
10 | + sanitize_params_hash(params) | |
11 | + # Api::Helpers | |
12 | + asset = :articles | |
13 | + context = environment | |
14 | + | |
15 | + profile = environment.profiles.find(params[:profile_id]) if params[:profile_id] | |
16 | + scope = profile.nil? ? environment.articles.is_public : profile.articles.is_public | |
17 | + scope = scope.where(:type => params[:type]) if params[:type] && !(params[:type] == 'Article') | |
18 | + scope = scope.where(make_conditions_with_parameter(params)) | |
19 | + scope = scope.joins(:categories).where(:categories => {:id => params[:category_ids]}) if params[:category_ids].present? | |
20 | + scope = scope.where('articles.children_count > 0') if params[:has_children].present? | |
21 | + query = params[:query] || "" | |
22 | + order = "more_recent" | |
23 | + | |
24 | + options = {:filter => order, :template_id => params[:template_id]} | |
25 | + | |
26 | + search_result = find_by_contents(asset, context, scope, query, {:page => 1}, options) | |
27 | + | |
28 | + articles = search_result[:results] | |
29 | + | |
30 | + present_articles(articles) | |
31 | + end | |
32 | + end | |
33 | + end | |
34 | + | |
35 | + end | |
36 | + end | |
37 | +end | ... | ... |
... | ... | @@ -0,0 +1,157 @@ |
1 | +require "uri" | |
2 | + | |
3 | +module Api | |
4 | + module V1 | |
5 | + class Session < Grape::API | |
6 | + | |
7 | + # Login to get token | |
8 | + # | |
9 | + # Parameters: | |
10 | + # login (*required) - user login or email | |
11 | + # password (required) - user password | |
12 | + # | |
13 | + # Example Request: | |
14 | + # POST http://localhost:3000/api/v1/login?login=adminuser&password=admin | |
15 | + post "/login" do | |
16 | + begin | |
17 | + user ||= User.authenticate(params[:login], params[:password], environment) | |
18 | + rescue User::UserNotActivated => e | |
19 | + render_api_error!(e.message, 401) | |
20 | + end | |
21 | + | |
22 | + return unauthorized! unless user | |
23 | + @current_user = user | |
24 | + present user, :with => Entities::UserLogin, :current_person => current_person | |
25 | + end | |
26 | + | |
27 | + post "/login_from_cookie" do | |
28 | + return unauthorized! if cookies[:auth_token].blank? | |
29 | + user = User.where(remember_token: cookies[:auth_token]).first | |
30 | + return unauthorized! unless user && user.activated? | |
31 | + @current_user = user | |
32 | + present user, :with => Entities::UserLogin, :current_person => current_person | |
33 | + end | |
34 | + | |
35 | + # Create user. | |
36 | + # | |
37 | + # Parameters: | |
38 | + # email (required) - Email | |
39 | + # password (required) - Password | |
40 | + # login - login | |
41 | + # Example Request: | |
42 | + # POST /register?email=some@mail.com&password=pas&password_confirmation=pas&login=some | |
43 | + params do | |
44 | + requires :email, type: String, desc: _("Email") | |
45 | + requires :login, type: String, desc: _("Login") | |
46 | + requires :password, type: String, desc: _("Password") | |
47 | + end | |
48 | + | |
49 | + post "/register" do | |
50 | + attrs = attributes_for_keys [:email, :login, :password, :password_confirmation] + environment.signup_person_fields | |
51 | + name = params[:name].present? ? params[:name] : attrs[:email] | |
52 | + attrs[:password_confirmation] = attrs[:password] if !attrs.has_key?(:password_confirmation) | |
53 | + user = User.new(attrs.merge(:name => name)) | |
54 | + | |
55 | + begin | |
56 | + user.signup! | |
57 | + user.generate_private_token! if user.activated? | |
58 | + present user, :with => Entities::UserLogin, :current_person => user.person | |
59 | + rescue ActiveRecord::RecordInvalid | |
60 | + message = user.errors.as_json.merge((user.person.present? ? user.person.errors : {}).as_json).to_json | |
61 | + render_api_error!(message, 400) | |
62 | + end | |
63 | + end | |
64 | + | |
65 | + params do | |
66 | + requires :activation_code, type: String, desc: _("Activation token") | |
67 | + end | |
68 | + | |
69 | + # Activate a user. | |
70 | + # | |
71 | + # Parameter: | |
72 | + # activation_code (required) - Activation token | |
73 | + # Example Request: | |
74 | + # PATCH /activate?activation_code=28259abd12cc6a64ef9399cf3286cb998b96aeaf | |
75 | + patch "/activate" do | |
76 | + user = User.find_by activation_code: params[:activation_code] | |
77 | + if user | |
78 | + unless user.environment.enabled?('admin_must_approve_new_users') | |
79 | + if user.activate | |
80 | + user.generate_private_token! | |
81 | + present user, :with => Entities::UserLogin, :current_person => current_person | |
82 | + end | |
83 | + else | |
84 | + if user.create_moderate_task | |
85 | + user.activation_code = nil | |
86 | + user.save! | |
87 | + | |
88 | + # Waiting for admin moderate user registration | |
89 | + status 202 | |
90 | + body({ | |
91 | + :message => 'Waiting for admin moderate user registration' | |
92 | + }) | |
93 | + end | |
94 | + end | |
95 | + else | |
96 | + # Token not found in database | |
97 | + render_api_error!(_('Token is invalid'), 412) | |
98 | + end | |
99 | + end | |
100 | + | |
101 | + # Request a new password. | |
102 | + # | |
103 | + # Parameters: | |
104 | + # value (required) - Email or login | |
105 | + # Example Request: | |
106 | + # POST /forgot_password?value=some@mail.com | |
107 | + post "/forgot_password" do | |
108 | + requestors = fetch_requestors(params[:value]) | |
109 | + not_found! if requestors.blank? | |
110 | + remote_ip = (request.respond_to?(:remote_ip) && request.remote_ip) || (env && env['REMOTE_ADDR']) | |
111 | + requestors.each do |requestor| | |
112 | + ChangePassword.create!(:requestor => requestor) | |
113 | + end | |
114 | + end | |
115 | + | |
116 | + # Resend activation code. | |
117 | + # | |
118 | + # Parameters: | |
119 | + # value (required) - Email or login | |
120 | + # Example Request: | |
121 | + # POST /resend_activation_code?value=some@mail.com | |
122 | + post "/resend_activation_code" do | |
123 | + requestors = fetch_requestors(params[:value]) | |
124 | + not_found! if requestors.blank? | |
125 | + remote_ip = (request.respond_to?(:remote_ip) && request.remote_ip) || (env && env['REMOTE_ADDR']) | |
126 | + requestors.each do |requestor| | |
127 | + requestor.user.resend_activation_code | |
128 | + end | |
129 | + present requestors.map(&:user), :with => Entities::UserLogin | |
130 | + end | |
131 | + | |
132 | + params do | |
133 | + requires :code, type: String, desc: _("Forgot password code") | |
134 | + end | |
135 | + # Change password | |
136 | + # | |
137 | + # Parameters: | |
138 | + # code (required) - Change password code | |
139 | + # password (required) | |
140 | + # password_confirmation (required) | |
141 | + # Example Request: | |
142 | + # PATCH /new_password?code=xxxx&password=secret&password_confirmation=secret | |
143 | + patch "/new_password" do | |
144 | + change_password = ChangePassword.find_by code: params[:code] | |
145 | + not_found! if change_password.nil? | |
146 | + | |
147 | + if change_password.update_attributes(:password => params[:password], :password_confirmation => params[:password_confirmation]) | |
148 | + change_password.finish | |
149 | + present change_password.requestor.user, :with => Entities::UserLogin, :current_person => current_person | |
150 | + else | |
151 | + something_wrong! | |
152 | + end | |
153 | + end | |
154 | + | |
155 | + end | |
156 | + end | |
157 | +end | ... | ... |
... | ... | @@ -0,0 +1,26 @@ |
1 | +module Api | |
2 | + module V1 | |
3 | + class Tags < Grape::API | |
4 | + before { authenticate! } | |
5 | + | |
6 | + resource :articles do | |
7 | + | |
8 | + resource ':id/tags' do | |
9 | + | |
10 | + get do | |
11 | + article = find_article(environment.articles, params[:id]) | |
12 | + present article.tag_list | |
13 | + end | |
14 | + | |
15 | + desc "Add a tag to an article" | |
16 | + post do | |
17 | + article = find_article(environment.articles, params[:id]) | |
18 | + article.tag_list=params[:tags] | |
19 | + article.save | |
20 | + present article.tag_list | |
21 | + end | |
22 | + end | |
23 | + end | |
24 | + end | |
25 | + end | |
26 | +end | ... | ... |
... | ... | @@ -0,0 +1,57 @@ |
1 | +module Api | |
2 | + module V1 | |
3 | + class Tasks < Grape::API | |
4 | +# before { authenticate! } | |
5 | + | |
6 | +# ARTICLE_TYPES = Article.descendants.map{|a| a.to_s} | |
7 | + | |
8 | + resource :tasks do | |
9 | + | |
10 | + # Collect tasks | |
11 | + # | |
12 | + # Parameters: | |
13 | + # from - date where the search will begin. If nothing is passed the default date will be the date of the first article created | |
14 | + # oldest - Collect the oldest articles. If nothing is passed the newest articles are collected | |
15 | + # limit - amount of articles returned. The default value is 20 | |
16 | + # | |
17 | + # Example Request: | |
18 | + # GET host/api/v1/tasks?from=2013-04-04-14:41:43&until=2015-04-04-14:41:43&limit=10&private_token=e96fff37c2238fdab074d1dcea8e6317 | |
19 | + get do | |
20 | + tasks = select_filtered_collection_of(environment, 'tasks', params) | |
21 | + tasks = tasks.select {|t| current_person.has_permission?(t.permission, environment)} | |
22 | + present_partial tasks, :with => Entities::Task | |
23 | + end | |
24 | + | |
25 | + desc "Return the task id" | |
26 | + get ':id' do | |
27 | + task = find_task(environment, params[:id]) | |
28 | + present_partial task, :with => Entities::Task | |
29 | + end | |
30 | + end | |
31 | + | |
32 | + kinds = %w[community person enterprise] | |
33 | + kinds.each do |kind| | |
34 | + resource kind.pluralize.to_sym do | |
35 | + segment "/:#{kind}_id" do | |
36 | + resource :tasks do | |
37 | + get do | |
38 | + profile = environment.send(kind.pluralize).find(params["#{kind}_id"]) | |
39 | + present_tasks(profile) | |
40 | + end | |
41 | + | |
42 | + get ':id' do | |
43 | + profile = environment.send(kind.pluralize).find(params["#{kind}_id"]) | |
44 | + present_task(profile) | |
45 | + end | |
46 | + | |
47 | + post do | |
48 | + profile = environment.send(kind.pluralize).find(params["#{kind}_id"]) | |
49 | + post_task(profile, params) | |
50 | + end | |
51 | + end | |
52 | + end | |
53 | + end | |
54 | + end | |
55 | + end | |
56 | + end | |
57 | +end | ... | ... |
... | ... | @@ -0,0 +1,43 @@ |
1 | +module Api | |
2 | + module V1 | |
3 | + class Users < Grape::API | |
4 | + | |
5 | + resource :users do | |
6 | + | |
7 | + get do | |
8 | + users = select_filtered_collection_of(environment, 'users', params) | |
9 | + users = users.select{|u| u.person.display_info_to? current_person} | |
10 | + present users, :with => Entities::User, :current_person => current_person | |
11 | + end | |
12 | + | |
13 | + get "/me" do | |
14 | + authenticate! | |
15 | + present current_user, :with => Entities::User, :current_person => current_person | |
16 | + end | |
17 | + | |
18 | + get ":id" do | |
19 | + user = environment.users.find_by id: params[:id] | |
20 | + if user | |
21 | + present user, :with => Entities::User, :current_person => current_person | |
22 | + else | |
23 | + not_found! | |
24 | + end | |
25 | + end | |
26 | + | |
27 | + get ":id/permissions" do | |
28 | + authenticate! | |
29 | + user = environment.users.find(params[:id]) | |
30 | + output = {} | |
31 | + user.person.role_assignments.map do |role_assigment| | |
32 | + if role_assigment.resource.respond_to?(:identifier) && role_assigment.resource.identifier == params[:profile] | |
33 | + output[:permissions] = role_assigment.role.permissions | |
34 | + end | |
35 | + end | |
36 | + present output | |
37 | + end | |
38 | + | |
39 | + end | |
40 | + | |
41 | + end | |
42 | + end | |
43 | +end | ... | ... |
app/controllers/public/api_controller.rb
... | ... | @@ -0,0 +1,14 @@ |
1 | +class ActivitiesCounterCacheJob | |
2 | + | |
3 | + def perform | |
4 | + person_activities_counts = ApplicationRecord.connection.execute("SELECT profiles.id, count(action_tracker.id) as count FROM profiles LEFT OUTER JOIN action_tracker ON profiles.id = action_tracker.user_id WHERE (action_tracker.created_at >= #{ApplicationRecord.connection.quote(ActionTracker::Record::RECENT_DELAY.days.ago.to_s(:db))}) AND ( (profiles.type = 'Person' ) ) GROUP BY profiles.id;") | |
5 | + organization_activities_counts = ApplicationRecord.connection.execute("SELECT profiles.id, count(action_tracker.id) as count FROM profiles LEFT OUTER JOIN action_tracker ON profiles.id = action_tracker.target_id WHERE (action_tracker.created_at >= #{ApplicationRecord.connection.quote(ActionTracker::Record::RECENT_DELAY.days.ago.to_s(:db))}) AND ( (profiles.type = 'Community' OR profiles.type = 'Enterprise' OR profiles.type = 'Organization' ) ) GROUP BY profiles.id;") | |
6 | + activities_counts = person_activities_counts.entries + organization_activities_counts.entries | |
7 | + activities_counts.each do |count| | |
8 | + update_sql = ApplicationRecord.__send__(:sanitize_sql, ["UPDATE profiles SET activities_count=? WHERE profiles.id=?;", count['count'].to_i, count['id'] ], '') | |
9 | + ApplicationRecord.connection.execute(update_sql) | |
10 | + end | |
11 | + Delayed::Job.enqueue(ActivitiesCounterCacheJob.new, {:priority => -3, :run_at => 1.day.from_now}) | |
12 | + end | |
13 | + | |
14 | +end | ... | ... |
... | ... | @@ -0,0 +1,11 @@ |
1 | +class CreateThumbnailsJob < Struct.new(:class_name, :file_id) | |
2 | + def perform | |
3 | + return unless class_name.constantize.exists?(file_id) | |
4 | + file = class_name.constantize.find(file_id) | |
5 | + file.create_thumbnails | |
6 | + article = Article.where(:image_id => file_id).first | |
7 | + if article | |
8 | + article.touch | |
9 | + end | |
10 | + end | |
11 | +end | ... | ... |
app/models/application_record.rb
1 | 1 | class ApplicationRecord < ActiveRecord::Base |
2 | 2 | |
3 | - self.abstract_class = true | |
4 | - | |
5 | - def self.postgresql? | |
6 | - self.connection.adapter_name == 'PostgreSQL' | |
7 | - end | |
3 | + self.abstract_class = true | |
4 | + self.store_full_sti_class = true | |
8 | 5 | |
9 | 6 | # an ActionView instance for rendering views on models |
10 | 7 | def self.action_view |
... | ... | @@ -25,7 +22,7 @@ class ApplicationRecord < ActiveRecord::Base |
25 | 22 | alias :meta_cache_key :cache_key |
26 | 23 | def cache_key |
27 | 24 | key = [Noosfero::VERSION, meta_cache_key] |
28 | - key.unshift(ApplicationRecord.connection.schema_search_path) if ApplicationRecord.postgresql? | |
25 | + key.unshift ApplicationRecord.connection.schema_search_path | |
29 | 26 | key.join('/') |
30 | 27 | end |
31 | 28 | ... | ... |
app/models/profile.rb
app/models/recent_documents_block.rb
app/views/admin_panel/set_portal_community.html.erb
... | ... | @@ -9,7 +9,7 @@ |
9 | 9 | <% end %> |
10 | 10 | <% end %> |
11 | 11 | <% else %> |
12 | - <%= _('Portal identifier: %s') % link_to(@portal_community.identifier, @portal_community.url) %> | |
12 | + <%= _('Portal identifier: %s').html_safe % link_to(@portal_community.identifier, @portal_community.url) %> | |
13 | 13 | |
14 | 14 | <% button_bar do %> |
15 | 15 | <%if @portal_community.environment.enabled?('use_portal_community') %> | ... | ... |
app/views/api/playground.html.erb
config.ru
config/application.rb
1 | -require File.expand_path('../boot', __FILE__) | |
1 | +require_relative 'boot' | |
2 | 2 | |
3 | 3 | require 'rails/all' |
4 | 4 | require 'active_support/dependencies' |
5 | 5 | |
6 | -# FIXME this silences the warnings about Rails 2.3-style plugins under | |
7 | -# vendor/plugins, which are deprecated. Hiding those warnings makes it easier | |
8 | -# to work for now, but we should really look at putting those plugins away. | |
6 | +# Silence Rails 5 deprecation warnings | |
9 | 7 | ActiveSupport::Deprecation.silenced = true |
10 | 8 | |
11 | 9 | Bundler.require(:default, :assets, Rails.env) |
10 | +$: << File.expand_path('../lib', File.dirname(__FILE__)) | |
11 | + | |
12 | +require_dependency 'noosfero' | |
13 | +require_dependency 'noosfero/plugin' | |
14 | +require_dependency 'noosfero/multi_tenancy' | |
12 | 15 | |
13 | 16 | module Noosfero |
14 | 17 | class Application < Rails::Application |
15 | 18 | |
16 | - require 'noosfero/plugin' | |
17 | - | |
18 | 19 | # The plugin xss_terminator(located in vendor/plugins/xss_terminator) and the helper |
19 | 20 | # SanitizeHelper(located in app/helpers/sanitize_helper.rb) use |
20 | 21 | # ALLOWED_TAGS and ALLOWED_ATTRIBUTES to make a sanitize with html. |
... | ... | @@ -30,9 +31,6 @@ module Noosfero |
30 | 31 | config.action_view.sanitized_allowed_tags = ALLOWED_TAGS |
31 | 32 | config.action_view.sanitized_allowed_attributes = ALLOWED_ATTRIBUTES |
32 | 33 | |
33 | - require 'noosfero/multi_tenancy' | |
34 | - config.middleware.use Noosfero::MultiTenancy::Middleware | |
35 | - | |
36 | 34 | config.action_controller.include_all_helpers = false |
37 | 35 | |
38 | 36 | # Settings in config/environments/* take precedence over those specified here. |
... | ... | @@ -40,10 +38,12 @@ module Noosfero |
40 | 38 | # -- all .rb files in that directory are automatically loaded. |
41 | 39 | |
42 | 40 | # Custom directories with classes and modules you want to be autoloadable. |
43 | - config.autoload_paths += %W( #{config.root.join('app', 'sweepers')} ) | |
44 | - config.autoload_paths += Dir["#{config.root}/lib"] | |
45 | - config.autoload_paths += Dir["#{config.root}/app/controllers/**/"] | |
46 | - config.autoload_paths += %W( #{config.root.join('test', 'mocks', Rails.env)} ) | |
41 | + config.autoload_paths << config.root.join('lib') | |
42 | + config.autoload_paths << config.root.join('app') | |
43 | + config.autoload_paths << config.root.join('app/jobs') | |
44 | + config.autoload_paths << config.root.join('app/sweepers') | |
45 | + config.autoload_paths.concat Dir["#{config.root}/app/controllers/**/"] | |
46 | + config.autoload_paths << config.root.join('test', 'mocks', Rails.env) | |
47 | 47 | |
48 | 48 | # Only load the plugins named here, in the order given (default is alphabetical). |
49 | 49 | # :all can be used as a placeholder for all plugins not explicitly named. |
... | ... | @@ -119,7 +119,8 @@ module Noosfero |
119 | 119 | |
120 | 120 | config.eager_load = true |
121 | 121 | |
122 | - Noosfero::Plugin.setup(config) | |
122 | + config.middleware.use Noosfero::MultiTenancy::Middleware | |
123 | 123 | |
124 | + Noosfero::Plugin.setup(config) | |
124 | 125 | end |
125 | 126 | end | ... | ... |
config/environment.rb
1 | -# Load the rails application | |
2 | -require File.expand_path('../application', __FILE__) | |
1 | +require_relative 'application' | |
3 | 2 | |
4 | -#FIXME Necessary hack to avoid the need of downgrading rubygems on rails 2.3.5 | |
5 | -# http://stackoverflow.com/questions/5564251/uninitialized-constant-activesupportdependenciesmutex | |
6 | -require 'thread' | |
7 | - | |
8 | -# Uncomment below to force Rails into production mode when | |
9 | -# you don't control web/app server and can't set it the proper way | |
10 | -#ENV['RAILS_ENV'] ||= 'production' | |
11 | - | |
12 | -# extra directories for controllers organization | |
13 | -extra_controller_dirs = %w[ | |
14 | -].map {|item| Rails.root.join(item) } | |
15 | - | |
16 | -# Add new inflection rules using the following format | |
17 | -# (all these examples are active by default): | |
18 | -# Inflector.inflections do |inflect| | |
19 | -# inflect.plural /^(ox)$/i, '\1en' | |
20 | -# inflect.singular /^(ox)en/i, '\1' | |
21 | -# inflect.irregular 'person', 'people' | |
22 | -# inflect.uncountable %w( fish sheep ) | |
23 | -# end | |
24 | - | |
25 | -# Include your application configuration below | |
26 | - | |
27 | -ActiveRecord::Base.store_full_sti_class = true | |
28 | - | |
29 | -#FIXME: Probably act_as_taggable_on is not being loaded or this should be on another place | |
30 | -#Tag.hierarchical = true | |
31 | - | |
32 | -# several local libraries | |
33 | -require_dependency 'noosfero' | |
34 | -#FIXME: error when call lib/sqlite_extention | |
35 | -#require 'sqlite_extension' | |
3 | +Noosfero::Application.initialize! | |
36 | 4 | |
37 | 5 | # load a local configuration if present, but not under test environment. |
38 | -if !['test', 'cucumber'].include?(ENV['RAILS_ENV']) | |
6 | +if ENV['RAILS_ENV'].in? %w[test cucumber] | |
39 | 7 | localconfigfile = Rails.root.join('config', 'local.rb') |
40 | - if File.exists?(localconfigfile) | |
41 | - require localconfigfile | |
42 | - end | |
8 | + require localconfigfile if File.exists? localconfigfile | |
43 | 9 | end |
44 | 10 | |
45 | -Noosfero::Application.initialize! | ... | ... |
... | ... | @@ -0,0 +1,31 @@ |
1 | +require 'pp' | |
2 | + | |
3 | +# third-party libraries | |
4 | +require 'will_paginate' | |
5 | +require 'will_paginate/array' | |
6 | +require 'nokogiri' | |
7 | + | |
8 | +# dependencies at vendor, firstly loaded on Gemfile | |
9 | +vendor = Dir.glob('vendor/{,plugins/}*') - ['vendor/plugins'] | |
10 | +vendor.each do |dir| | |
11 | + init_rb = "#{Rails.root}/#{dir}/init.rb" | |
12 | + require init_rb if File.file? init_rb | |
13 | +end | |
14 | + | |
15 | +# extensions | |
16 | +require 'extensions' | |
17 | + | |
18 | +# locally-developed modules | |
19 | +require 'acts_as_filesystem' | |
20 | +require 'acts_as_having_settings' | |
21 | +require 'acts_as_having_boxes' | |
22 | +require 'acts_as_having_image' | |
23 | +require 'acts_as_having_posts' | |
24 | +require 'acts_as_customizable' | |
25 | +require 'route_if' | |
26 | +require 'maybe_add_http' | |
27 | +require 'set_profile_region_from_city_state' | |
28 | +require 'authenticated_system' | |
29 | +require 'needs_profile' | |
30 | +require 'white_list_filter' | |
31 | + | ... | ... |
config/initializers/dependencies.rb
... | ... | @@ -1,28 +0,0 @@ |
1 | -require 'pp' | |
2 | - | |
3 | -# third-party libraries | |
4 | -require 'will_paginate' | |
5 | -require 'will_paginate/array' | |
6 | -require 'nokogiri' | |
7 | - | |
8 | -# dependencies at vendor, firstly loaded on Gemfile | |
9 | -vendor = Dir.glob('vendor/{,plugins/}*') - ['vendor/plugins'] | |
10 | -vendor.each do |dir| | |
11 | - init_rb = "#{Rails.root}/#{dir}/init.rb" | |
12 | - require init_rb if File.file? init_rb | |
13 | -end | |
14 | - | |
15 | -# locally-developed modules | |
16 | -require 'acts_as_filesystem' | |
17 | -require 'acts_as_having_settings' | |
18 | -require 'acts_as_having_boxes' | |
19 | -require 'acts_as_having_image' | |
20 | -require 'acts_as_having_posts' | |
21 | -require 'acts_as_customizable' | |
22 | -require 'route_if' | |
23 | -require 'maybe_add_http' | |
24 | -require 'set_profile_region_from_city_state' | |
25 | -require 'authenticated_system' | |
26 | -require 'needs_profile' | |
27 | -require 'white_list_filter' | |
28 | - |
config/initializers/plugins.rb
lib/activities_counter_cache_job.rb
... | ... | @@ -1,14 +0,0 @@ |
1 | -class ActivitiesCounterCacheJob | |
2 | - | |
3 | - def perform | |
4 | - person_activities_counts = ApplicationRecord.connection.execute("SELECT profiles.id, count(action_tracker.id) as count FROM profiles LEFT OUTER JOIN action_tracker ON profiles.id = action_tracker.user_id WHERE (action_tracker.created_at >= #{ApplicationRecord.connection.quote(ActionTracker::Record::RECENT_DELAY.days.ago.to_s(:db))}) AND ( (profiles.type = 'Person' ) ) GROUP BY profiles.id;") | |
5 | - organization_activities_counts = ApplicationRecord.connection.execute("SELECT profiles.id, count(action_tracker.id) as count FROM profiles LEFT OUTER JOIN action_tracker ON profiles.id = action_tracker.target_id WHERE (action_tracker.created_at >= #{ApplicationRecord.connection.quote(ActionTracker::Record::RECENT_DELAY.days.ago.to_s(:db))}) AND ( (profiles.type = 'Community' OR profiles.type = 'Enterprise' OR profiles.type = 'Organization' ) ) GROUP BY profiles.id;") | |
6 | - activities_counts = person_activities_counts.entries + organization_activities_counts.entries | |
7 | - activities_counts.each do |count| | |
8 | - update_sql = ApplicationRecord.__send__(:sanitize_sql, ["UPDATE profiles SET activities_count=? WHERE profiles.id=?;", count['count'].to_i, count['id'] ], '') | |
9 | - ApplicationRecord.connection.execute(update_sql) | |
10 | - end | |
11 | - Delayed::Job.enqueue(ActivitiesCounterCacheJob.new, {:priority => -3, :run_at => 1.day.from_now}) | |
12 | - end | |
13 | - | |
14 | -end |
lib/acts_as_customizable.rb
lib/acts_as_filesystem.rb
... | ... | @@ -33,7 +33,7 @@ module ActsAsFileSystem |
33 | 33 | module ClassMethods |
34 | 34 | |
35 | 35 | def build_ancestry(parent_id = nil, ancestry = '') |
36 | - ApplicationRecord.transaction do | |
36 | + ActiveRecord::Base.transaction do | |
37 | 37 | self.base_class.where(parent_id: parent_id).each do |node| |
38 | 38 | node.update_column :ancestry, ancestry |
39 | 39 | |
... | ... | @@ -263,5 +263,5 @@ module ActsAsFileSystem |
263 | 263 | end |
264 | 264 | end |
265 | 265 | |
266 | -ApplicationRecord.extend ActsAsFileSystem::ActsMethods | |
266 | +ActiveRecord::Base.extend ActsAsFileSystem::ActsMethods | |
267 | 267 | ... | ... |
lib/acts_as_having_boxes.rb
lib/acts_as_having_image.rb
lib/acts_as_having_posts.rb
lib/acts_as_having_settings.rb
lib/code_numbering.rb
lib/create_thumbnails_job.rb
... | ... | @@ -1,11 +0,0 @@ |
1 | -class CreateThumbnailsJob < Struct.new(:class_name, :file_id) | |
2 | - def perform | |
3 | - return unless class_name.constantize.exists?(file_id) | |
4 | - file = class_name.constantize.find(file_id) | |
5 | - file.create_thumbnails | |
6 | - article = Article.where(:image_id => file_id).first | |
7 | - if article | |
8 | - article.touch | |
9 | - end | |
10 | - end | |
11 | -end |
lib/delayed_attachment_fu.rb
... | ... | @@ -0,0 +1,10 @@ |
1 | +ActiveRecord::Calculations.class_eval do | |
2 | + def count_with_distinct column_name=self.primary_key | |
3 | + if column_name | |
4 | + distinct.count_without_distinct column_name | |
5 | + else | |
6 | + count_without_distinct | |
7 | + end | |
8 | + end | |
9 | + alias_method_chain :count, :distinct | |
10 | +end | ... | ... |
... | ... | @@ -0,0 +1,20 @@ |
1 | + | |
2 | +# on STI classes tike Article and Profile, plugins' extensions | |
3 | +# on associations should be reflected on descendants | |
4 | +module ActiveRecord | |
5 | + module Reflection | |
6 | + | |
7 | + class << self | |
8 | + | |
9 | + def add_reflection_with_descendants(ar, name, reflection) | |
10 | + self.add_reflection_without_descendants ar, name, reflection | |
11 | + ar.descendants.each do |k| | |
12 | + k._reflections.merge!(name.to_s => reflection) | |
13 | + end if ar.base_class == ar | |
14 | + end | |
15 | + | |
16 | + alias_method_chain :add_reflection, :descendants | |
17 | + | |
18 | + end | |
19 | + end | |
20 | +end | ... | ... |
... | ... | @@ -0,0 +1,39 @@ |
1 | +class Integer | |
2 | + def to_humanreadable | |
3 | + value = self | |
4 | + if value < 1023 | |
5 | + return "%i bytes" % value | |
6 | + end | |
7 | + value /= 1024 | |
8 | + | |
9 | + if value < 1023 | |
10 | + return "%1.1f KB" % value | |
11 | + end | |
12 | + value /= 1024 | |
13 | + | |
14 | + if value < 1023 | |
15 | + return "%1.1f MB" % value | |
16 | + end | |
17 | + value /= 1024 | |
18 | + | |
19 | + if value < 1023 | |
20 | + return "%1.1f GB" % value | |
21 | + end | |
22 | + value /= 1024 | |
23 | + | |
24 | + if value < 1023 | |
25 | + return "%1.1f TB" % value | |
26 | + end | |
27 | + value /= 1024 | |
28 | + | |
29 | + if value < 1023 | |
30 | + return "%1.1f PB" % value | |
31 | + end | |
32 | + value /= 1024 | |
33 | + | |
34 | + if value < 1023 | |
35 | + return "%1.1f EB" % value | |
36 | + end | |
37 | + value /= 1024 | |
38 | + end | |
39 | +end | ... | ... |
... | ... | @@ -0,0 +1,93 @@ |
1 | +# encoding: utf-8 | |
2 | + | |
3 | +class String | |
4 | + | |
5 | + TRANSLITERATIONS = { | |
6 | + [ 'Á', 'À', 'À', 'Â', 'Ã', 'Ä', 'Å' ] => 'A', | |
7 | + [ 'á', 'à', 'à', 'â', 'ã', 'ä', 'å' ,'ª' ] => 'a', | |
8 | + [ 'É', 'È', 'Ê', 'Ë' ] => 'E', | |
9 | + [ 'é', 'è', 'ê', 'ë' ] => 'e', | |
10 | + [ 'Í', 'Ì', 'Î', 'Ï' ] => 'I', | |
11 | + [ 'í', 'ì', 'î', 'ï' ] => 'i', | |
12 | + [ 'Ó', 'Ò', 'Ô', 'Ö', 'Õ', 'º' ] => 'O', | |
13 | + [ 'ó', 'ò', 'ô', 'ö', 'õ', 'º' ] => 'o', | |
14 | + [ 'Ú', 'Ù', 'Û', 'Ü' ] => 'U', | |
15 | + [ 'ú', 'ù', 'û', 'ü' ] => 'u', | |
16 | + [ 'ß' ] => 'ss', | |
17 | + [ 'Ç' ] => 'C', | |
18 | + [ 'ç' ] => 'c', | |
19 | + [ 'Ñ' ] => 'N', | |
20 | + [ 'ñ' ] => 'n', | |
21 | + [ 'Ÿ' ] => 'Y', | |
22 | + [ 'ÿ' ] => 'y', | |
23 | +# Cyrillic alphabet transliteration | |
24 | + [ 'а', 'А' ] => 'a', | |
25 | + [ 'б', 'Б' ] => 'b', | |
26 | + [ 'в', 'В' ] => 'v', | |
27 | + [ 'г', 'Г' ] => 'g', | |
28 | + [ 'д', 'Д' ] => 'd', | |
29 | + [ 'е', 'Е' ] => 'e', | |
30 | + [ 'ё', 'Ё' ] => 'yo', | |
31 | + [ 'ж', 'Ж' ] => 'zh', | |
32 | + [ 'з', 'З' ] => 'z', | |
33 | + [ 'и', 'И' ] => 'i', | |
34 | + [ 'й', 'Й' ] => 'y', | |
35 | + [ 'к', 'К' ] => 'k', | |
36 | + [ 'л', 'Л' ] => 'l', | |
37 | + [ 'м', 'М' ] => 'm', | |
38 | + [ 'н', 'Н' ] => 'n', | |
39 | + [ 'о', 'О' ] => 'o', | |
40 | + [ 'п', 'П' ] => 'p', | |
41 | + [ 'р', 'Р' ] => 'r', | |
42 | + [ 'с', 'С' ] => 's', | |
43 | + [ 'т', 'Т' ] => 't', | |
44 | + [ 'у', 'У' ] => 'u', | |
45 | + [ 'ф', 'Ф' ] => 'f', | |
46 | + [ 'х', 'Х' ] => 'h', | |
47 | + [ 'ц', 'Ц' ] => 'ts', | |
48 | + [ 'ч', 'Ч' ] => 'ch', | |
49 | + [ 'ш', 'Ш' ] => 'sh', | |
50 | + [ 'щ', 'Щ' ] => 'sch', | |
51 | + [ 'э', 'Э' ] => 'e', | |
52 | + [ 'ю', 'Ю' ] => 'yu', | |
53 | + [ 'я', 'Я' ] => 'ya', | |
54 | + [ 'ы', 'Ы' ] => 'i', | |
55 | + [ 'ь', 'Ь' ] => '', | |
56 | + [ 'ъ', 'Ъ' ] => '', | |
57 | +# Ukrainian lovely letters | |
58 | + [ 'і', 'І' ] => 'i', | |
59 | + [ 'ї', 'Ї' ] => 'yi', | |
60 | + [ 'є', 'Є' ] => 'ye', | |
61 | + [ 'ґ', 'Ґ' ] => 'g', | |
62 | + } | |
63 | + | |
64 | + # transliterate a string (assumed to contain UTF-8 data) | |
65 | + # into ASCII by replacing non-ascii characters to their | |
66 | + # ASCII. | |
67 | + # | |
68 | + # The transliteration is, of course, lossy, and its performance is poor. | |
69 | + # Don't abuse this method. | |
70 | + def transliterate | |
71 | + | |
72 | + new = self.dup | |
73 | + TRANSLITERATIONS.each { |from,to| | |
74 | + from.each { |seq| | |
75 | + new.gsub!(seq, to) | |
76 | + } | |
77 | + } | |
78 | + new | |
79 | + end | |
80 | + | |
81 | + def to_slug | |
82 | + transliterate.downcase.gsub(/[^[[:word:]]~\s:;+=_."'`-]/, '').gsub(/[\s:;+=_"'`-]+/, '-').gsub(/-$/, '').gsub(/^-/, '').to_s | |
83 | + end | |
84 | + | |
85 | + def to_css_class | |
86 | + underscore.dasherize.gsub('/','_') | |
87 | + end | |
88 | + | |
89 | + def fix_i18n | |
90 | + self.sub('{fn} ', '') | |
91 | + end | |
92 | + | |
93 | +end | ... | ... |
lib/noosfero.rb
1 | -# encoding: utf-8 | |
1 | +require_relative 'noosfero/version' | |
2 | +require_relative 'noosfero/constants' | |
2 | 3 | |
3 | 4 | module Noosfero |
4 | 5 | |
... | ... | @@ -106,6 +107,3 @@ module Noosfero |
106 | 107 | |
107 | 108 | end |
108 | 109 | |
109 | -require 'noosfero/version' | |
110 | -require 'noosfero/constants' | |
111 | -require 'noosfero/core_ext' | ... | ... |
lib/noosfero/api/api.rb
... | ... | @@ -1,94 +0,0 @@ |
1 | -require 'grape' | |
2 | -#require 'rack/contrib' | |
3 | -Dir["#{Rails.root}/lib/noosfero/api/*.rb"].each {|file| require file unless file =~ /api\.rb/} | |
4 | - | |
5 | -module Noosfero | |
6 | - module API | |
7 | - class API < Grape::API | |
8 | - use Rack::JSONP | |
9 | - | |
10 | - logger = Logger.new(File.join(Rails.root, 'log', "#{ENV['RAILS_ENV'] || 'production'}_api.log")) | |
11 | - logger.formatter = GrapeLogging::Formatters::Default.new | |
12 | - #use GrapeLogging::Middleware::RequestLogger, { logger: logger } | |
13 | - | |
14 | - rescue_from :all do |e| | |
15 | - logger.error e | |
16 | - error! e.message, 500 | |
17 | - end | |
18 | - | |
19 | - @@NOOSFERO_CONF = nil | |
20 | - def self.NOOSFERO_CONF | |
21 | - if @@NOOSFERO_CONF | |
22 | - @@NOOSFERO_CONF | |
23 | - else | |
24 | - file = Rails.root.join('config', 'noosfero.yml') | |
25 | - @@NOOSFERO_CONF = File.exists?(file) ? YAML.load_file(file)[Rails.env] || {} : {} | |
26 | - end | |
27 | - end | |
28 | - | |
29 | - before { set_locale } | |
30 | - before { setup_multitenancy } | |
31 | - before { detect_stuff_by_domain } | |
32 | - before { filter_disabled_plugins_endpoints } | |
33 | - before { init_noosfero_plugins } | |
34 | - after { set_session_cookie } | |
35 | - | |
36 | - version 'v1' | |
37 | - prefix [ENV['RAILS_RELATIVE_URL_ROOT'], "api"].compact.join('/') | |
38 | - format :json | |
39 | - content_type :txt, "text/plain" | |
40 | - | |
41 | - helpers APIHelpers | |
42 | - | |
43 | - mount V1::Articles | |
44 | - mount V1::Comments | |
45 | - mount V1::Users | |
46 | - mount V1::Communities | |
47 | - mount V1::People | |
48 | - mount V1::Enterprises | |
49 | - mount V1::Categories | |
50 | - mount V1::Tasks | |
51 | - mount V1::Tags | |
52 | - mount V1::Environments | |
53 | - mount V1::Search | |
54 | - mount V1::Contacts | |
55 | - mount V1::Boxes | |
56 | - mount V1::Blocks | |
57 | - mount V1::Profiles | |
58 | - mount V1::Activities | |
59 | - | |
60 | - mount Session | |
61 | - | |
62 | - # hook point which allow plugins to add Grape::API extensions to API::API | |
63 | - #finds for plugins which has api mount points classes defined (the class should extends Grape::API) | |
64 | - @plugins = Noosfero::Plugin.all.map { |p| p.constantize } | |
65 | - @plugins.each do |klass| | |
66 | - if klass.public_methods.include? :api_mount_points | |
67 | - klass.api_mount_points.each do |mount_class| | |
68 | - mount mount_class if mount_class && ( mount_class < Grape::API ) | |
69 | - end | |
70 | - end | |
71 | - end | |
72 | - | |
73 | - def self.endpoint_unavailable?(endpoint, environment) | |
74 | - api_class = endpoint.options[:app] || endpoint.options[:for] | |
75 | - if api_class.present? | |
76 | - klass = api_class.name.deconstantize.constantize | |
77 | - return klass < Noosfero::Plugin && !environment.plugin_enabled?(klass) | |
78 | - end | |
79 | - end | |
80 | - | |
81 | - class << self | |
82 | - def endpoints_with_plugins(environment = nil) | |
83 | - if environment.present? | |
84 | - cloned_endpoints = endpoints_without_plugins.dup | |
85 | - cloned_endpoints.delete_if { |endpoint| endpoint_unavailable?(endpoint, environment) } | |
86 | - else | |
87 | - endpoints_without_plugins | |
88 | - end | |
89 | - end | |
90 | - alias_method_chain :endpoints, :plugins | |
91 | - end | |
92 | - end | |
93 | - end | |
94 | -end |
lib/noosfero/api/entities.rb
... | ... | @@ -1,269 +0,0 @@ |
1 | -module Noosfero | |
2 | - module API | |
3 | - module Entities | |
4 | - | |
5 | - Entity.format_with :timestamp do |date| | |
6 | - date.strftime('%Y/%m/%d %H:%M:%S') if date | |
7 | - end | |
8 | - | |
9 | - PERMISSIONS = { | |
10 | - :admin => 0, | |
11 | - :self => 10, | |
12 | - :private_content => 20, | |
13 | - :logged_user => 30, | |
14 | - :anonymous => 40 | |
15 | - } | |
16 | - | |
17 | - def self.can_display_profile_field? profile, options, permission_options={} | |
18 | - permissions={:field => "", :permission => :private_content} | |
19 | - permissions.merge!(permission_options) | |
20 | - field = permissions[:field] | |
21 | - permission = permissions[:permission] | |
22 | - return true if profile.public? && profile.public_fields.map{|f| f.to_sym}.include?(field.to_sym) | |
23 | - | |
24 | - current_person = options[:current_person] | |
25 | - | |
26 | - current_permission = if current_person.present? | |
27 | - if current_person.is_admin? | |
28 | - :admin | |
29 | - elsif current_person == profile | |
30 | - :self | |
31 | - elsif profile.display_private_info_to?(current_person) | |
32 | - :private_content | |
33 | - else | |
34 | - :logged_user | |
35 | - end | |
36 | - else | |
37 | - :anonymous | |
38 | - end | |
39 | - PERMISSIONS[current_permission] <= PERMISSIONS[permission] | |
40 | - end | |
41 | - | |
42 | - class Image < Entity | |
43 | - root 'images', 'image' | |
44 | - | |
45 | - expose :url do |image, options| | |
46 | - image.public_filename | |
47 | - end | |
48 | - | |
49 | - expose :icon_url do |image, options| | |
50 | - image.public_filename(:icon) | |
51 | - end | |
52 | - | |
53 | - expose :minor_url do |image, options| | |
54 | - image.public_filename(:minor) | |
55 | - end | |
56 | - | |
57 | - expose :portrait_url do |image, options| | |
58 | - image.public_filename(:portrait) | |
59 | - end | |
60 | - | |
61 | - expose :thumb_url do |image, options| | |
62 | - image.public_filename(:thumb) | |
63 | - end | |
64 | - end | |
65 | - | |
66 | - class CategoryBase < Entity | |
67 | - root 'categories', 'category' | |
68 | - expose :name, :id, :slug | |
69 | - end | |
70 | - | |
71 | - class Category < CategoryBase | |
72 | - root 'categories', 'category' | |
73 | - expose :full_name do |category, options| | |
74 | - category.full_name | |
75 | - end | |
76 | - expose :parent, :using => CategoryBase, if: { parent: true } | |
77 | - expose :children, :using => CategoryBase, if: { children: true } | |
78 | - expose :image, :using => Image | |
79 | - expose :display_color | |
80 | - end | |
81 | - | |
82 | - class Region < Category | |
83 | - root 'regions', 'region' | |
84 | - expose :parent_id | |
85 | - end | |
86 | - | |
87 | - class Block < Entity | |
88 | - root 'blocks', 'block' | |
89 | - expose :id, :type, :settings, :position, :enabled | |
90 | - expose :mirror, :mirror_block_id, :title | |
91 | - expose :api_content, if: lambda { |object, options| options[:display_api_content] || object.display_api_content_by_default? } | |
92 | - end | |
93 | - | |
94 | - class Box < Entity | |
95 | - root 'boxes', 'box' | |
96 | - expose :id, :position | |
97 | - expose :blocks, :using => Block | |
98 | - end | |
99 | - | |
100 | - class Profile < Entity | |
101 | - expose :identifier, :name, :id | |
102 | - expose :created_at, :format_with => :timestamp | |
103 | - expose :updated_at, :format_with => :timestamp | |
104 | - expose :additional_data do |profile, options| | |
105 | - hash ={} | |
106 | - profile.public_values.each do |value| | |
107 | - hash[value.custom_field.name]=value.value | |
108 | - end | |
109 | - | |
110 | - private_values = profile.custom_field_values - profile.public_values | |
111 | - private_values.each do |value| | |
112 | - if Entities.can_display_profile_field?(profile,options) | |
113 | - hash[value.custom_field.name]=value.value | |
114 | - end | |
115 | - end | |
116 | - hash | |
117 | - end | |
118 | - expose :image, :using => Image | |
119 | - expose :region, :using => Region | |
120 | - expose :type | |
121 | - expose :custom_header | |
122 | - expose :custom_footer | |
123 | - end | |
124 | - | |
125 | - class UserBasic < Entity | |
126 | - expose :id | |
127 | - expose :login | |
128 | - end | |
129 | - | |
130 | - class Person < Profile | |
131 | - root 'people', 'person' | |
132 | - expose :user, :using => UserBasic, documentation: {type: 'User', desc: 'The user data of a person' } | |
133 | - expose :vote_count | |
134 | - expose :comments_count do |person, options| | |
135 | - person.comments.count | |
136 | - end | |
137 | - expose :following_articles_count do |person, options| | |
138 | - person.following_articles.count | |
139 | - end | |
140 | - expose :articles_count do |person, options| | |
141 | - person.articles.count | |
142 | - end | |
143 | - end | |
144 | - | |
145 | - class Enterprise < Profile | |
146 | - root 'enterprises', 'enterprise' | |
147 | - end | |
148 | - | |
149 | - class Community < Profile | |
150 | - root 'communities', 'community' | |
151 | - expose :description | |
152 | - expose :admins, :if => lambda { |community, options| community.display_info_to? options[:current_person]} do |community, options| | |
153 | - community.admins.map{|admin| {"name"=>admin.name, "id"=>admin.id, "username" => admin.identifier}} | |
154 | - end | |
155 | - expose :categories, :using => Category | |
156 | - expose :members, :using => Person , :if => lambda{ |community, options| community.display_info_to? options[:current_person] } | |
157 | - end | |
158 | - | |
159 | - class CommentBase < Entity | |
160 | - expose :body, :title, :id | |
161 | - expose :created_at, :format_with => :timestamp | |
162 | - expose :author, :using => Profile | |
163 | - expose :reply_of, :using => CommentBase | |
164 | - end | |
165 | - | |
166 | - class Comment < CommentBase | |
167 | - root 'comments', 'comment' | |
168 | - expose :children, as: :replies, :using => Comment | |
169 | - end | |
170 | - | |
171 | - class ArticleBase < Entity | |
172 | - root 'articles', 'article' | |
173 | - expose :id | |
174 | - expose :body | |
175 | - expose :abstract, documentation: {type: 'String', desc: 'Teaser of the body'} | |
176 | - expose :created_at, :format_with => :timestamp | |
177 | - expose :updated_at, :format_with => :timestamp | |
178 | - expose :title, :documentation => {:type => "String", :desc => "Title of the article"} | |
179 | - expose :created_by, :as => :author, :using => Profile, :documentation => {type: 'Profile', desc: 'The profile author that create the article'} | |
180 | - expose :profile, :using => Profile, :documentation => {type: 'Profile', desc: 'The profile associated with the article'} | |
181 | - expose :categories, :using => Category | |
182 | - expose :image, :using => Image | |
183 | - expose :votes_for | |
184 | - expose :votes_against | |
185 | - expose :setting | |
186 | - expose :position | |
187 | - expose :hits | |
188 | - expose :start_date | |
189 | - expose :end_date, :documentation => {type: 'DateTime', desc: 'The date of finish of the article'} | |
190 | - expose :tag_list | |
191 | - expose :children_count | |
192 | - expose :slug, :documentation => {:type => "String", :desc => "Trimmed and parsed name of a article"} | |
193 | - expose :path | |
194 | - expose :followers_count | |
195 | - expose :votes_count | |
196 | - expose :comments_count | |
197 | - expose :archived, :documentation => {:type => "Boolean", :desc => "Defines if a article is readonly"} | |
198 | - expose :type | |
199 | - expose :comments, using: CommentBase, :if => lambda{|obj,opt| opt[:params] && ['1','true',true].include?(opt[:params][:show_comments])} | |
200 | - expose :published | |
201 | - expose :accept_comments?, as: :accept_comments | |
202 | - end | |
203 | - | |
204 | - class Article < ArticleBase | |
205 | - root 'articles', 'article' | |
206 | - expose :parent, :using => ArticleBase | |
207 | - expose :children, :using => ArticleBase do |article, options| | |
208 | - article.children.published.limit(Noosfero::API::V1::Articles::MAX_PER_PAGE) | |
209 | - end | |
210 | - end | |
211 | - | |
212 | - class User < Entity | |
213 | - root 'users', 'user' | |
214 | - | |
215 | - attrs = [:id,:login,:email,:activated?] | |
216 | - aliases = {:activated? => :activated} | |
217 | - | |
218 | - attrs.each do |attribute| | |
219 | - name = aliases.has_key?(attribute) ? aliases[attribute] : attribute | |
220 | - expose attribute, :as => name, :if => lambda{|user,options| Entities.can_display_profile_field?(user.person, options, {:field => attribute})} | |
221 | - end | |
222 | - | |
223 | - expose :person, :using => Person, :if => lambda{|user,options| user.person.display_info_to? options[:current_person]} | |
224 | - expose :permissions, :if => lambda{|user,options| Entities.can_display_profile_field?(user.person, options, {:field => :permissions, :permission => :self})} do |user, options| | |
225 | - output = {} | |
226 | - user.person.role_assignments.map do |role_assigment| | |
227 | - if role_assigment.resource.respond_to?(:identifier) && !role_assigment.role.nil? | |
228 | - output[role_assigment.resource.identifier] = role_assigment.role.permissions | |
229 | - end | |
230 | - end | |
231 | - output | |
232 | - end | |
233 | - end | |
234 | - | |
235 | - class UserLogin < User | |
236 | - root 'users', 'user' | |
237 | - expose :private_token, documentation: {type: 'String', desc: 'A valid authentication code for post/delete api actions'}, if: lambda {|object, options| object.activated? } | |
238 | - end | |
239 | - | |
240 | - class Task < Entity | |
241 | - root 'tasks', 'task' | |
242 | - expose :id | |
243 | - expose :type | |
244 | - end | |
245 | - | |
246 | - class Environment < Entity | |
247 | - expose :name | |
248 | - expose :id | |
249 | - expose :description | |
250 | - expose :settings, if: lambda { |instance, options| options[:is_admin] } | |
251 | - end | |
252 | - | |
253 | - class Tag < Entity | |
254 | - root 'tags', 'tag' | |
255 | - expose :name | |
256 | - end | |
257 | - | |
258 | - class Activity < Entity | |
259 | - root 'activities', 'activity' | |
260 | - expose :id, :params, :verb, :created_at, :updated_at, :comments_count, :visible | |
261 | - expose :user, :using => Profile | |
262 | - expose :target do |activity, opts| | |
263 | - type_map = {Profile => ::Profile, ArticleBase => ::Article}.find {|h| activity.target.kind_of?(h.last)} | |
264 | - type_map.first.represent(activity.target) unless type_map.nil? | |
265 | - end | |
266 | - end | |
267 | - end | |
268 | - end | |
269 | -end |
lib/noosfero/api/entity.rb
... | ... | @@ -1,25 +0,0 @@ |
1 | -class Noosfero::API::Entity < Grape::Entity | |
2 | - | |
3 | - def initialize(object, options = {}) | |
4 | - object = nil if object.is_a? Exception | |
5 | - super object, options | |
6 | - end | |
7 | - | |
8 | - def self.represent(objects, options = {}) | |
9 | - if options[:has_exception] | |
10 | - data = super objects, options.merge(is_inner_data: true) | |
11 | - if objects.is_a? Exception | |
12 | - data.merge ok: false, error: { | |
13 | - type: objects.class.name, | |
14 | - message: objects.message | |
15 | - } | |
16 | - else | |
17 | - data = data.serializable_hash if data.is_a? Noosfero::API::Entity | |
18 | - data.merge ok: true, error: { type: 'Success', message: '' } | |
19 | - end | |
20 | - else | |
21 | - super objects, options | |
22 | - end | |
23 | - end | |
24 | - | |
25 | -end |
lib/noosfero/api/helpers.rb
... | ... | @@ -1,425 +0,0 @@ |
1 | -require 'grape' | |
2 | -require 'base64' | |
3 | -require 'tempfile' | |
4 | -require_relative '../../find_by_contents' | |
5 | - | |
6 | -module Noosfero; | |
7 | - module API | |
8 | - module APIHelpers | |
9 | - PRIVATE_TOKEN_PARAM = :private_token | |
10 | - DEFAULT_ALLOWED_PARAMETERS = [:parent_id, :from, :until, :content_type, :author_id, :identifier, :archived] | |
11 | - | |
12 | - include SanitizeParams | |
13 | - include Noosfero::Plugin::HotSpot | |
14 | - include ForgotPasswordHelper | |
15 | - include SearchTermHelper | |
16 | - | |
17 | - def set_locale | |
18 | - I18n.locale = (params[:lang] || request.env['HTTP_ACCEPT_LANGUAGE'] || 'en') | |
19 | - end | |
20 | - | |
21 | - def init_noosfero_plugins | |
22 | - plugins | |
23 | - end | |
24 | - | |
25 | - def current_user | |
26 | - private_token = (params[PRIVATE_TOKEN_PARAM] || headers['Private-Token']).to_s | |
27 | - @current_user ||= User.find_by private_token: private_token | |
28 | - @current_user ||= plugins.dispatch("api_custom_login", request).first | |
29 | - @current_user | |
30 | - end | |
31 | - | |
32 | - def current_person | |
33 | - current_user.person unless current_user.nil? | |
34 | - end | |
35 | - | |
36 | - def is_admin?(environment) | |
37 | - return false unless current_user | |
38 | - return current_person.is_admin?(environment) | |
39 | - end | |
40 | - | |
41 | - def logout | |
42 | - @current_user = nil | |
43 | - end | |
44 | - | |
45 | - def environment | |
46 | - @environment | |
47 | - end | |
48 | - | |
49 | - def present_partial(model, options) | |
50 | - if(params[:fields].present?) | |
51 | - begin | |
52 | - fields = JSON.parse(params[:fields]) | |
53 | - if fields.present? | |
54 | - options.merge!(fields.symbolize_keys.slice(:only, :except)) | |
55 | - end | |
56 | - rescue | |
57 | - fields = params[:fields] | |
58 | - fields = fields.split(',') if fields.kind_of?(String) | |
59 | - options[:only] = Array.wrap(fields) | |
60 | - end | |
61 | - end | |
62 | - present model, options | |
63 | - end | |
64 | - | |
65 | - include FindByContents | |
66 | - | |
67 | - #################################################################### | |
68 | - #### SEARCH | |
69 | - #################################################################### | |
70 | - def multiple_search?(searches=nil) | |
71 | - ['index', 'category_index'].include?(params[:action]) || (searches && searches.size > 1) | |
72 | - end | |
73 | - #################################################################### | |
74 | - | |
75 | - def logger | |
76 | - logger = Logger.new(File.join(Rails.root, 'log', "#{ENV['RAILS_ENV'] || 'production'}_api.log")) | |
77 | - logger.formatter = GrapeLogging::Formatters::Default.new | |
78 | - logger | |
79 | - end | |
80 | - | |
81 | - def limit | |
82 | - limit = params[:limit].to_i | |
83 | - limit = default_limit if limit <= 0 | |
84 | - limit | |
85 | - end | |
86 | - | |
87 | - def period(from_date, until_date) | |
88 | - return nil if from_date.nil? && until_date.nil? | |
89 | - | |
90 | - begin_period = from_date.nil? ? Time.at(0).to_datetime : from_date | |
91 | - end_period = until_date.nil? ? DateTime.now : until_date | |
92 | - | |
93 | - begin_period..end_period | |
94 | - end | |
95 | - | |
96 | - def parse_content_type(content_type) | |
97 | - return nil if content_type.blank? | |
98 | - content_type.split(',').map do |content_type| | |
99 | - content_type.camelcase | |
100 | - end | |
101 | - end | |
102 | - | |
103 | - def find_article(articles, id) | |
104 | - article = articles.find(id) | |
105 | - article.display_to?(current_person) ? article : forbidden! | |
106 | - end | |
107 | - | |
108 | - def post_article(asset, params) | |
109 | - return forbidden! unless current_person.can_post_content?(asset) | |
110 | - | |
111 | - klass_type = params[:content_type] || params[:article].delete(:type) || TinyMceArticle.name | |
112 | - return forbidden! unless klass_type.constantize <= Article | |
113 | - | |
114 | - article = klass_type.constantize.new(params[:article]) | |
115 | - article.last_changed_by = current_person | |
116 | - article.created_by= current_person | |
117 | - article.profile = asset | |
118 | - | |
119 | - if !article.save | |
120 | - render_api_errors!(article.errors.full_messages) | |
121 | - end | |
122 | - present_partial article, :with => Entities::Article | |
123 | - end | |
124 | - | |
125 | - def present_article(asset) | |
126 | - article = find_article(asset.articles, params[:id]) | |
127 | - present_partial article, :with => Entities::Article, :params => params | |
128 | - end | |
129 | - | |
130 | - def present_articles_for_asset(asset, method = 'articles') | |
131 | - articles = find_articles(asset, method) | |
132 | - present_articles(articles) | |
133 | - end | |
134 | - | |
135 | - def present_articles(articles) | |
136 | - present_partial paginate(articles), :with => Entities::Article, :params => params | |
137 | - end | |
138 | - | |
139 | - def find_articles(asset, method = 'articles') | |
140 | - articles = select_filtered_collection_of(asset, method, params) | |
141 | - if current_person.present? | |
142 | - articles = articles.display_filter(current_person, nil) | |
143 | - else | |
144 | - articles = articles.published | |
145 | - end | |
146 | - articles | |
147 | - end | |
148 | - | |
149 | - def find_task(asset, id) | |
150 | - task = asset.tasks.find(id) | |
151 | - current_person.has_permission?(task.permission, asset) ? task : forbidden! | |
152 | - end | |
153 | - | |
154 | - def post_task(asset, params) | |
155 | - klass_type= params[:content_type].nil? ? 'Task' : params[:content_type] | |
156 | - return forbidden! unless klass_type.constantize <= Task | |
157 | - | |
158 | - task = klass_type.constantize.new(params[:task]) | |
159 | - task.requestor_id = current_person.id | |
160 | - task.target_id = asset.id | |
161 | - task.target_type = 'Profile' | |
162 | - | |
163 | - if !task.save | |
164 | - render_api_errors!(task.errors.full_messages) | |
165 | - end | |
166 | - present_partial task, :with => Entities::Task | |
167 | - end | |
168 | - | |
169 | - def present_task(asset) | |
170 | - task = find_task(asset, params[:id]) | |
171 | - present_partial task, :with => Entities::Task | |
172 | - end | |
173 | - | |
174 | - def present_tasks(asset) | |
175 | - tasks = select_filtered_collection_of(asset, 'tasks', params) | |
176 | - tasks = tasks.select {|t| current_person.has_permission?(t.permission, asset)} | |
177 | - return forbidden! if tasks.empty? && !current_person.has_permission?(:perform_task, asset) | |
178 | - present_partial tasks, :with => Entities::Task | |
179 | - end | |
180 | - | |
181 | - def make_conditions_with_parameter(params = {}) | |
182 | - parsed_params = parser_params(params) | |
183 | - conditions = {} | |
184 | - from_date = DateTime.parse(parsed_params.delete(:from)) if parsed_params[:from] | |
185 | - until_date = DateTime.parse(parsed_params.delete(:until)) if parsed_params[:until] | |
186 | - | |
187 | - conditions[:type] = parse_content_type(parsed_params.delete(:content_type)) unless parsed_params[:content_type].nil? | |
188 | - | |
189 | - conditions[:created_at] = period(from_date, until_date) if from_date || until_date | |
190 | - conditions.merge!(parsed_params) | |
191 | - | |
192 | - conditions | |
193 | - end | |
194 | - | |
195 | - # changing make_order_with_parameters to avoid sql injection | |
196 | - def make_order_with_parameters(object, method, params) | |
197 | - order = "created_at DESC" | |
198 | - unless params[:order].blank? | |
199 | - if params[:order].include? '\'' or params[:order].include? '"' | |
200 | - order = "created_at DESC" | |
201 | - elsif ['RANDOM()', 'RANDOM'].include? params[:order].upcase | |
202 | - order = 'RANDOM()' | |
203 | - else | |
204 | - field_name, direction = params[:order].split(' ') | |
205 | - assoc = object.class.reflect_on_association(method.to_sym) | |
206 | - if !field_name.blank? and assoc | |
207 | - if assoc.klass.attribute_names.include? field_name | |
208 | - if direction.present? and ['ASC','DESC'].include? direction.upcase | |
209 | - order = "#{field_name} #{direction.upcase}" | |
210 | - end | |
211 | - end | |
212 | - end | |
213 | - end | |
214 | - end | |
215 | - return order | |
216 | - end | |
217 | - | |
218 | - def make_timestamp_with_parameters_and_method(params, method) | |
219 | - timestamp = nil | |
220 | - if params[:timestamp] | |
221 | - datetime = DateTime.parse(params[:timestamp]) | |
222 | - table_name = method.to_s.singularize.camelize.constantize.table_name | |
223 | - timestamp = "#{table_name}.updated_at >= '#{datetime}'" | |
224 | - end | |
225 | - | |
226 | - timestamp | |
227 | - end | |
228 | - | |
229 | - def by_reference(scope, params) | |
230 | - reference_id = params[:reference_id].to_i == 0 ? nil : params[:reference_id].to_i | |
231 | - if reference_id.nil? | |
232 | - scope | |
233 | - else | |
234 | - created_at = scope.find(reference_id).created_at | |
235 | - scope.send("#{params.key?(:oldest) ? 'older_than' : 'younger_than'}", created_at) | |
236 | - end | |
237 | - end | |
238 | - | |
239 | - def by_categories(scope, params) | |
240 | - category_ids = params[:category_ids] | |
241 | - if category_ids.nil? | |
242 | - scope | |
243 | - else | |
244 | - scope.joins(:categories).where(:categories => {:id => category_ids}) | |
245 | - end | |
246 | - end | |
247 | - | |
248 | - def select_filtered_collection_of(object, method, params) | |
249 | - conditions = make_conditions_with_parameter(params) | |
250 | - order = make_order_with_parameters(object,method,params) | |
251 | - timestamp = make_timestamp_with_parameters_and_method(params, method) | |
252 | - | |
253 | - objects = object.send(method) | |
254 | - objects = by_reference(objects, params) | |
255 | - objects = by_categories(objects, params) | |
256 | - | |
257 | - objects = objects.where(conditions).where(timestamp).reorder(order) | |
258 | - | |
259 | - params[:page] ||= 1 | |
260 | - params[:per_page] ||= limit | |
261 | - paginate(objects) | |
262 | - end | |
263 | - | |
264 | - def authenticate! | |
265 | - unauthorized! unless current_user | |
266 | - end | |
267 | - | |
268 | - def profiles_for_person(profiles, person) | |
269 | - if person | |
270 | - profiles.listed_for_person(person) | |
271 | - else | |
272 | - profiles.visible | |
273 | - end | |
274 | - end | |
275 | - | |
276 | - # Checks the occurrences of uniqueness of attributes, each attribute must be present in the params hash | |
277 | - # or a Bad Request error is invoked. | |
278 | - # | |
279 | - # Parameters: | |
280 | - # keys (unique) - A hash consisting of keys that must be unique | |
281 | - def unique_attributes!(obj, keys) | |
282 | - keys.each do |key| | |
283 | - cant_be_saved_request!(key) if obj.find_by(key.to_s => params[key]) | |
284 | - end | |
285 | - end | |
286 | - | |
287 | - def attributes_for_keys(keys) | |
288 | - attrs = {} | |
289 | - keys.each do |key| | |
290 | - attrs[key] = params[key] if params[key].present? or (params.has_key?(key) and params[key] == false) | |
291 | - end | |
292 | - attrs | |
293 | - end | |
294 | - | |
295 | - ########################################## | |
296 | - # error helpers # | |
297 | - ########################################## | |
298 | - | |
299 | - def not_found! | |
300 | - render_api_error!('404 Not found', 404) | |
301 | - end | |
302 | - | |
303 | - def forbidden! | |
304 | - render_api_error!('403 Forbidden', 403) | |
305 | - end | |
306 | - | |
307 | - def cant_be_saved_request!(attribute) | |
308 | - message = _("(Invalid request) %s can't be saved") % attribute | |
309 | - render_api_error!(message, 400) | |
310 | - end | |
311 | - | |
312 | - def bad_request!(attribute) | |
313 | - message = _("(Invalid request) %s not given") % attribute | |
314 | - render_api_error!(message, 400) | |
315 | - end | |
316 | - | |
317 | - def something_wrong! | |
318 | - message = _("Something wrong happened") | |
319 | - render_api_error!(message, 400) | |
320 | - end | |
321 | - | |
322 | - def unauthorized! | |
323 | - render_api_error!(_('Unauthorized'), 401) | |
324 | - end | |
325 | - | |
326 | - def not_allowed! | |
327 | - render_api_error!(_('Method Not Allowed'), 405) | |
328 | - end | |
329 | - | |
330 | - # javascript_console_message is supposed to be executed as console.log() | |
331 | - def render_api_error!(user_message, status, log_message = nil, javascript_console_message = nil) | |
332 | - message_hash = {'message' => user_message, :code => status} | |
333 | - message_hash[:javascript_console_message] = javascript_console_message if javascript_console_message.present? | |
334 | - log_msg = "#{status}, User message: #{user_message}" | |
335 | - log_msg = "#{log_message}, #{log_msg}" if log_message.present? | |
336 | - log_msg = "#{log_msg}, Javascript Console Message: #{javascript_console_message}" if javascript_console_message.present? | |
337 | - logger.error log_msg unless Rails.env.test? | |
338 | - error!(message_hash, status) | |
339 | - end | |
340 | - | |
341 | - def render_api_errors!(messages) | |
342 | - messages = messages.to_a if messages.class == ActiveModel::Errors | |
343 | - render_api_error!(messages.join(','), 400) | |
344 | - end | |
345 | - | |
346 | - protected | |
347 | - | |
348 | - def set_session_cookie | |
349 | - cookies['_noosfero_api_session'] = { value: @current_user.private_token, httponly: true } if @current_user.present? | |
350 | - end | |
351 | - | |
352 | - def setup_multitenancy | |
353 | - Noosfero::MultiTenancy.setup!(request.host) | |
354 | - end | |
355 | - | |
356 | - def detect_stuff_by_domain | |
357 | - @domain = Domain.by_name(request.host) | |
358 | - if @domain.nil? | |
359 | - @environment = Environment.default | |
360 | - if @environment.nil? && Rails.env.development? | |
361 | - # This should only happen in development ... | |
362 | - @environment = Environment.create!(:name => "Noosfero", :is_default => true) | |
363 | - end | |
364 | - else | |
365 | - @environment = @domain.environment | |
366 | - end | |
367 | - end | |
368 | - | |
369 | - def filter_disabled_plugins_endpoints | |
370 | - not_found! if Noosfero::API::API.endpoint_unavailable?(self, @environment) | |
371 | - end | |
372 | - | |
373 | - def asset_with_image params | |
374 | - if params.has_key? :image_builder | |
375 | - asset_api_params = params | |
376 | - asset_api_params[:image_builder] = base64_to_uploadedfile(asset_api_params[:image_builder]) | |
377 | - return asset_api_params | |
378 | - end | |
379 | - params | |
380 | - end | |
381 | - | |
382 | - def base64_to_uploadedfile(base64_image) | |
383 | - tempfile = base64_to_tempfile base64_image | |
384 | - converted_image = base64_image | |
385 | - converted_image[:tempfile] = tempfile | |
386 | - return {uploaded_data: ActionDispatch::Http::UploadedFile.new(converted_image)} | |
387 | - end | |
388 | - | |
389 | - def base64_to_tempfile base64_image | |
390 | - base64_img_str = base64_image[:tempfile] | |
391 | - decoded_base64_str = Base64.decode64(base64_img_str) | |
392 | - tempfile = Tempfile.new(base64_image[:filename]) | |
393 | - tempfile.write(decoded_base64_str.encode("ascii-8bit").force_encoding("utf-8")) | |
394 | - tempfile.rewind | |
395 | - tempfile | |
396 | - end | |
397 | - private | |
398 | - | |
399 | - def parser_params(params) | |
400 | - parsed_params = {} | |
401 | - params.map do |k,v| | |
402 | - parsed_params[k.to_sym] = v if DEFAULT_ALLOWED_PARAMETERS.include?(k.to_sym) | |
403 | - end | |
404 | - parsed_params | |
405 | - end | |
406 | - | |
407 | - def default_limit | |
408 | - 20 | |
409 | - end | |
410 | - | |
411 | - def parse_content_type(content_type) | |
412 | - return nil if content_type.blank? | |
413 | - content_type.split(',').map do |content_type| | |
414 | - content_type.camelcase | |
415 | - end | |
416 | - end | |
417 | - | |
418 | - def period(from_date, until_date) | |
419 | - begin_period = from_date.nil? ? Time.at(0).to_datetime : from_date | |
420 | - end_period = until_date.nil? ? DateTime.now : until_date | |
421 | - begin_period..end_period | |
422 | - end | |
423 | - end | |
424 | - end | |
425 | -end |
lib/noosfero/api/session.rb
... | ... | @@ -1,157 +0,0 @@ |
1 | -require "uri" | |
2 | - | |
3 | -module Noosfero | |
4 | - module API | |
5 | - class Session < Grape::API | |
6 | - | |
7 | - # Login to get token | |
8 | - # | |
9 | - # Parameters: | |
10 | - # login (*required) - user login or email | |
11 | - # password (required) - user password | |
12 | - # | |
13 | - # Example Request: | |
14 | - # POST http://localhost:3000/api/v1/login?login=adminuser&password=admin | |
15 | - post "/login" do | |
16 | - begin | |
17 | - user ||= User.authenticate(params[:login], params[:password], environment) | |
18 | - rescue User::UserNotActivated => e | |
19 | - render_api_error!(e.message, 401) | |
20 | - end | |
21 | - | |
22 | - return unauthorized! unless user | |
23 | - @current_user = user | |
24 | - present user, :with => Entities::UserLogin, :current_person => current_person | |
25 | - end | |
26 | - | |
27 | - post "/login_from_cookie" do | |
28 | - return unauthorized! if cookies[:auth_token].blank? | |
29 | - user = User.where(remember_token: cookies[:auth_token]).first | |
30 | - return unauthorized! unless user && user.activated? | |
31 | - @current_user = user | |
32 | - present user, :with => Entities::UserLogin, :current_person => current_person | |
33 | - end | |
34 | - | |
35 | - # Create user. | |
36 | - # | |
37 | - # Parameters: | |
38 | - # email (required) - Email | |
39 | - # password (required) - Password | |
40 | - # login - login | |
41 | - # Example Request: | |
42 | - # POST /register?email=some@mail.com&password=pas&password_confirmation=pas&login=some | |
43 | - params do | |
44 | - requires :email, type: String, desc: _("Email") | |
45 | - requires :login, type: String, desc: _("Login") | |
46 | - requires :password, type: String, desc: _("Password") | |
47 | - end | |
48 | - | |
49 | - post "/register" do | |
50 | - attrs = attributes_for_keys [:email, :login, :password, :password_confirmation] + environment.signup_person_fields | |
51 | - name = params[:name].present? ? params[:name] : attrs[:email] | |
52 | - attrs[:password_confirmation] = attrs[:password] if !attrs.has_key?(:password_confirmation) | |
53 | - user = User.new(attrs.merge(:name => name)) | |
54 | - | |
55 | - begin | |
56 | - user.signup! | |
57 | - user.generate_private_token! if user.activated? | |
58 | - present user, :with => Entities::UserLogin, :current_person => user.person | |
59 | - rescue ActiveRecord::RecordInvalid | |
60 | - message = user.errors.as_json.merge((user.person.present? ? user.person.errors : {}).as_json).to_json | |
61 | - render_api_error!(message, 400) | |
62 | - end | |
63 | - end | |
64 | - | |
65 | - params do | |
66 | - requires :activation_code, type: String, desc: _("Activation token") | |
67 | - end | |
68 | - | |
69 | - # Activate a user. | |
70 | - # | |
71 | - # Parameter: | |
72 | - # activation_code (required) - Activation token | |
73 | - # Example Request: | |
74 | - # PATCH /activate?activation_code=28259abd12cc6a64ef9399cf3286cb998b96aeaf | |
75 | - patch "/activate" do | |
76 | - user = User.find_by activation_code: params[:activation_code] | |
77 | - if user | |
78 | - unless user.environment.enabled?('admin_must_approve_new_users') | |
79 | - if user.activate | |
80 | - user.generate_private_token! | |
81 | - present user, :with => Entities::UserLogin, :current_person => current_person | |
82 | - end | |
83 | - else | |
84 | - if user.create_moderate_task | |
85 | - user.activation_code = nil | |
86 | - user.save! | |
87 | - | |
88 | - # Waiting for admin moderate user registration | |
89 | - status 202 | |
90 | - body({ | |
91 | - :message => 'Waiting for admin moderate user registration' | |
92 | - }) | |
93 | - end | |
94 | - end | |
95 | - else | |
96 | - # Token not found in database | |
97 | - render_api_error!(_('Token is invalid'), 412) | |
98 | - end | |
99 | - end | |
100 | - | |
101 | - # Request a new password. | |
102 | - # | |
103 | - # Parameters: | |
104 | - # value (required) - Email or login | |
105 | - # Example Request: | |
106 | - # POST /forgot_password?value=some@mail.com | |
107 | - post "/forgot_password" do | |
108 | - requestors = fetch_requestors(params[:value]) | |
109 | - not_found! if requestors.blank? | |
110 | - remote_ip = (request.respond_to?(:remote_ip) && request.remote_ip) || (env && env['REMOTE_ADDR']) | |
111 | - requestors.each do |requestor| | |
112 | - ChangePassword.create!(:requestor => requestor) | |
113 | - end | |
114 | - end | |
115 | - | |
116 | - # Resend activation code. | |
117 | - # | |
118 | - # Parameters: | |
119 | - # value (required) - Email or login | |
120 | - # Example Request: | |
121 | - # POST /resend_activation_code?value=some@mail.com | |
122 | - post "/resend_activation_code" do | |
123 | - requestors = fetch_requestors(params[:value]) | |
124 | - not_found! if requestors.blank? | |
125 | - remote_ip = (request.respond_to?(:remote_ip) && request.remote_ip) || (env && env['REMOTE_ADDR']) | |
126 | - requestors.each do |requestor| | |
127 | - requestor.user.resend_activation_code | |
128 | - end | |
129 | - present requestors.map(&:user), :with => Entities::UserLogin | |
130 | - end | |
131 | - | |
132 | - params do | |
133 | - requires :code, type: String, desc: _("Forgot password code") | |
134 | - end | |
135 | - # Change password | |
136 | - # | |
137 | - # Parameters: | |
138 | - # code (required) - Change password code | |
139 | - # password (required) | |
140 | - # password_confirmation (required) | |
141 | - # Example Request: | |
142 | - # PATCH /new_password?code=xxxx&password=secret&password_confirmation=secret | |
143 | - patch "/new_password" do | |
144 | - change_password = ChangePassword.find_by code: params[:code] | |
145 | - not_found! if change_password.nil? | |
146 | - | |
147 | - if change_password.update_attributes(:password => params[:password], :password_confirmation => params[:password_confirmation]) | |
148 | - change_password.finish | |
149 | - present change_password.requestor.user, :with => Entities::UserLogin, :current_person => current_person | |
150 | - else | |
151 | - something_wrong! | |
152 | - end | |
153 | - end | |
154 | - | |
155 | - end | |
156 | - end | |
157 | -end |
lib/noosfero/api/v1/activities.rb
... | ... | @@ -1,22 +0,0 @@ |
1 | -module Noosfero | |
2 | - module API | |
3 | - module V1 | |
4 | - class Activities < Grape::API | |
5 | - before { authenticate! } | |
6 | - | |
7 | - resource :profiles do | |
8 | - | |
9 | - get ':id/activities' do | |
10 | - profile = Profile.find_by id: params[:id] | |
11 | - | |
12 | - not_found! if profile.blank? || profile.secret || !profile.visible | |
13 | - forbidden! if !profile.secret && profile.visible && !profile.display_private_info_to?(current_person) | |
14 | - | |
15 | - activities = profile.activities.map(&:activity) | |
16 | - present activities, :with => Entities::Activity, :current_person => current_person | |
17 | - end | |
18 | - end | |
19 | - end | |
20 | - end | |
21 | - end | |
22 | -end |
lib/noosfero/api/v1/articles.rb
... | ... | @@ -1,305 +0,0 @@ |
1 | -module Noosfero | |
2 | - module API | |
3 | - module V1 | |
4 | - class Articles < Grape::API | |
5 | - | |
6 | - ARTICLE_TYPES = Article.descendants.map{|a| a.to_s} | |
7 | - | |
8 | - MAX_PER_PAGE = 50 | |
9 | - | |
10 | - resource :articles do | |
11 | - | |
12 | - paginate max_per_page: MAX_PER_PAGE | |
13 | - # Collect articles | |
14 | - # | |
15 | - # Parameters: | |
16 | - # from - date where the search will begin. If nothing is passed the default date will be the date of the first article created | |
17 | - # oldest - Collect the oldest articles. If nothing is passed the newest articles are collected | |
18 | - # limit - amount of articles returned. The default value is 20 | |
19 | - # | |
20 | - # Example Request: | |
21 | - # GET host/api/v1/articles?from=2013-04-04-14:41:43&until=2015-04-04-14:41:43&limit=10&private_token=e96fff37c2238fdab074d1dcea8e6317 | |
22 | - | |
23 | - desc 'Return all articles of all kinds' do | |
24 | - detail 'Get all articles filtered by fields in query params' | |
25 | - params Noosfero::API::Entities::Article.documentation | |
26 | - success Noosfero::API::Entities::Article | |
27 | - failure [[403, 'Forbidden']] | |
28 | - named 'ArticlesList' | |
29 | - headers [ | |
30 | - 'Per-Page' => { | |
31 | - description: 'Total number of records', | |
32 | - required: false | |
33 | - } | |
34 | - ] | |
35 | - end | |
36 | - get do | |
37 | - present_articles_for_asset(environment) | |
38 | - end | |
39 | - | |
40 | - desc "Return one article by id" do | |
41 | - detail 'Get only one article by id. If not found the "forbidden" http error is showed' | |
42 | - params Noosfero::API::Entities::Article.documentation | |
43 | - success Noosfero::API::Entities::Article | |
44 | - failure [[403, 'Forbidden']] | |
45 | - named 'ArticleById' | |
46 | - end | |
47 | - get ':id', requirements: {id: /[0-9]+/} do | |
48 | - present_article(environment) | |
49 | - end | |
50 | - | |
51 | - post ':id' do | |
52 | - article = environment.articles.find(params[:id]) | |
53 | - return forbidden! unless article.allow_edit?(current_person) | |
54 | - article.update_attributes!(asset_with_image(params[:article])) | |
55 | - present_partial article, :with => Entities::Article | |
56 | - end | |
57 | - | |
58 | - desc 'Report a abuse and/or violent content in a article by id' do | |
59 | - detail 'Submit a abuse (in general, a content violation) report about a specific article' | |
60 | - params Noosfero::API::Entities::Article.documentation | |
61 | - failure [[400, 'Bad Request']] | |
62 | - named 'ArticleReportAbuse' | |
63 | - end | |
64 | - post ':id/report_abuse' do | |
65 | - article = find_article(environment.articles, params[:id]) | |
66 | - profile = article.profile | |
67 | - begin | |
68 | - abuse_report = AbuseReport.new(:reason => params[:report_abuse]) | |
69 | - if !params[:content_type].blank? | |
70 | - article = params[:content_type].constantize.find(params[:content_id]) | |
71 | - abuse_report.content = article_reported_version(article) | |
72 | - end | |
73 | - | |
74 | - current_person.register_report(abuse_report, profile) | |
75 | - | |
76 | - if !params[:content_type].blank? | |
77 | - abuse_report = AbuseReport.find_by reporter_id: current_person.id, abuse_complaint_id: profile.opened_abuse_complaint.id | |
78 | - Delayed::Job.enqueue DownloadReportedImagesJob.new(abuse_report, article) | |
79 | - end | |
80 | - | |
81 | - { | |
82 | - :success => true, | |
83 | - :message => _('Your abuse report was registered. The administrators are reviewing your report.'), | |
84 | - } | |
85 | - rescue Exception => exception | |
86 | - #logger.error(exception.to_s) | |
87 | - render_api_error!(_('Your report couldn\'t be saved due to some problem. Please contact the administrator.'), 400) | |
88 | - end | |
89 | - | |
90 | - end | |
91 | - | |
92 | - desc "Returns the articles I voted" do | |
93 | - detail 'Get the Articles I make a vote' | |
94 | - failure [[403, 'Forbidden']] | |
95 | - named 'ArticleFollowers' | |
96 | - end | |
97 | - #FIXME refactor this method | |
98 | - get 'voted_by_me' do | |
99 | - present_articles(current_person.votes.where(:voteable_type => 'Article').collect(&:voteable)) | |
100 | - end | |
101 | - | |
102 | - desc 'Perform a vote on a article by id' do | |
103 | - detail 'Vote on a specific article with values: 1 (if you like) or -1 (if not)' | |
104 | - params Noosfero::API::Entities::UserLogin.documentation | |
105 | - failure [[401,'Unauthorized']] | |
106 | - named 'ArticleVote' | |
107 | - end | |
108 | - post ':id/vote' do | |
109 | - authenticate! | |
110 | - value = (params[:value] || 1).to_i | |
111 | - # FIXME verify allowed values | |
112 | - render_api_error!('Vote value not allowed', 400) unless [-1, 1].include?(value) | |
113 | - article = find_article(environment.articles, params[:id]) | |
114 | - begin | |
115 | - vote = Vote.new(:voteable => article, :voter => current_person, :vote => value) | |
116 | - {:vote => vote.save!} | |
117 | - rescue ActiveRecord::RecordInvalid => e | |
118 | - render_api_error!(e.message, 400) | |
119 | - end | |
120 | - end | |
121 | - | |
122 | - desc "Returns the total followers for the article" do | |
123 | - detail 'Get the followers of a specific article by id' | |
124 | - failure [[403, 'Forbidden']] | |
125 | - named 'ArticleFollowers' | |
126 | - end | |
127 | - get ':id/followers' do | |
128 | - article = find_article(environment.articles, params[:id]) | |
129 | - total = article.person_followers.count | |
130 | - {:total_followers => total} | |
131 | - end | |
132 | - | |
133 | - desc "Return the articles followed by me" | |
134 | - get 'followed_by_me' do | |
135 | - present_articles_for_asset(current_person, 'following_articles') | |
136 | - end | |
137 | - | |
138 | - desc "Add a follower for the article" do | |
139 | - detail 'Add the current user identified by private token, like a follower of a article' | |
140 | - params Noosfero::API::Entities::UserLogin.documentation | |
141 | - failure [[401, 'Unauthorized']] | |
142 | - named 'ArticleFollow' | |
143 | - end | |
144 | - post ':id/follow' do | |
145 | - authenticate! | |
146 | - article = find_article(environment.articles, params[:id]) | |
147 | - if article.article_followers.exists?(:person_id => current_person.id) | |
148 | - {:success => false, :already_follow => true} | |
149 | - else | |
150 | - article_follower = ArticleFollower.new | |
151 | - article_follower.article = article | |
152 | - article_follower.person = current_person | |
153 | - article_follower.save! | |
154 | - {:success => true} | |
155 | - end | |
156 | - end | |
157 | - | |
158 | - desc 'Return the children of a article identified by id' do | |
159 | - detail 'Get all children articles of a specific article' | |
160 | - params Noosfero::API::Entities::Article.documentation | |
161 | - failure [[403, 'Forbidden']] | |
162 | - named 'ArticleChildren' | |
163 | - end | |
164 | - | |
165 | - paginate per_page: MAX_PER_PAGE, max_per_page: MAX_PER_PAGE | |
166 | - get ':id/children' do | |
167 | - article = find_article(environment.articles, params[:id]) | |
168 | - | |
169 | - #TODO make tests for this situation | |
170 | - votes_order = params.delete(:order) if params[:order]=='votes_score' | |
171 | - articles = select_filtered_collection_of(article, 'children', params) | |
172 | - articles = articles.display_filter(current_person, article.profile) | |
173 | - | |
174 | - #TODO make tests for this situation | |
175 | - if votes_order | |
176 | - articles = articles.joins('left join votes on articles.id=votes.voteable_id').group('articles.id').reorder('sum(coalesce(votes.vote, 0)) DESC') | |
177 | - end | |
178 | - Article.hit(articles) | |
179 | - present_articles(articles) | |
180 | - end | |
181 | - | |
182 | - desc 'Return one child of a article identified by id' do | |
183 | - detail 'Get a child of a specific article' | |
184 | - params Noosfero::API::Entities::Article.documentation | |
185 | - success Noosfero::API::Entities::Article | |
186 | - failure [[403, 'Forbidden']] | |
187 | - named 'ArticleChild' | |
188 | - end | |
189 | - get ':id/children/:child_id' do | |
190 | - article = find_article(environment.articles, params[:id]) | |
191 | - child = find_article(article.children, params[:child_id]) | |
192 | - child.hit | |
193 | - present_partial child, :with => Entities::Article | |
194 | - end | |
195 | - | |
196 | - desc 'Suggest a article to another profile' do | |
197 | - detail 'Suggest a article to another profile (person, community...)' | |
198 | - params Noosfero::API::Entities::Article.documentation | |
199 | - success Noosfero::API::Entities::Task | |
200 | - failure [[401,'Unauthorized']] | |
201 | - named 'ArticleSuggest' | |
202 | - end | |
203 | - post ':id/children/suggest' do | |
204 | - authenticate! | |
205 | - parent_article = environment.articles.find(params[:id]) | |
206 | - | |
207 | - suggest_article = SuggestArticle.new | |
208 | - suggest_article.article = params[:article] | |
209 | - suggest_article.article[:parent_id] = parent_article.id | |
210 | - suggest_article.target = parent_article.profile | |
211 | - suggest_article.requestor = current_person | |
212 | - | |
213 | - unless suggest_article.save | |
214 | - render_api_errors!(suggest_article.article_object.errors.full_messages) | |
215 | - end | |
216 | - present_partial suggest_article, :with => Entities::Task | |
217 | - end | |
218 | - | |
219 | - # Example Request: | |
220 | - # POST api/v1/articles/:id/children?private_token=234298743290432&article[name]=title&article[body]=body | |
221 | - desc 'Add a child article to a parent identified by id' do | |
222 | - detail 'Create a new article and associate to a parent' | |
223 | - params Noosfero::API::Entities::Article.documentation | |
224 | - success Noosfero::API::Entities::Article | |
225 | - failure [[401,'Unauthorized']] | |
226 | - named 'ArticleAddChild' | |
227 | - end | |
228 | - post ':id/children' do | |
229 | - parent_article = environment.articles.find(params[:id]) | |
230 | - params[:article][:parent_id] = parent_article.id | |
231 | - post_article(parent_article.profile, params) | |
232 | - end | |
233 | - end | |
234 | - | |
235 | - resource :profiles do | |
236 | - get ':id/home_page' do | |
237 | - profiles = environment.profiles | |
238 | - profiles = profiles.visible_for_person(current_person) | |
239 | - profile = profiles.find_by id: params[:id] | |
240 | - present_partial profile.home_page, :with => Entities::Article | |
241 | - end | |
242 | - end | |
243 | - | |
244 | - kinds = %w[profile community person enterprise] | |
245 | - kinds.each do |kind| | |
246 | - resource kind.pluralize.to_sym do | |
247 | - segment "/:#{kind}_id" do | |
248 | - resource :articles do | |
249 | - | |
250 | - desc "Return all articles associate with a profile of type #{kind}" do | |
251 | - detail 'Get a list of articles of a profile' | |
252 | - params Noosfero::API::Entities::Article.documentation | |
253 | - success Noosfero::API::Entities::Article | |
254 | - failure [[403, 'Forbidden']] | |
255 | - named 'ArticlesOfProfile' | |
256 | - end | |
257 | - get do | |
258 | - profile = environment.send(kind.pluralize).find(params["#{kind}_id"]) | |
259 | - | |
260 | - if params[:path].present? | |
261 | - article = profile.articles.find_by path: params[:path] | |
262 | - if !article || !article.display_to?(current_person) | |
263 | - article = forbidden! | |
264 | - end | |
265 | - | |
266 | - present_partial article, :with => Entities::Article | |
267 | - else | |
268 | - | |
269 | - present_articles_for_asset(profile) | |
270 | - end | |
271 | - end | |
272 | - | |
273 | - desc "Return a article associate with a profile of type #{kind}" do | |
274 | - detail 'Get only one article of a profile' | |
275 | - params Noosfero::API::Entities::Article.documentation | |
276 | - success Noosfero::API::Entities::Article | |
277 | - failure [[403, 'Forbidden']] | |
278 | - named 'ArticleOfProfile' | |
279 | - end | |
280 | - get ':id' do | |
281 | - profile = environment.send(kind.pluralize).find(params["#{kind}_id"]) | |
282 | - present_article(profile) | |
283 | - end | |
284 | - | |
285 | - # Example Request: | |
286 | - # POST api/v1/{people,communities,enterprises}/:asset_id/articles?private_token=234298743290432&article[name]=title&article[body]=body | |
287 | - desc "Add a new article associated with a profile of type #{kind}" do | |
288 | - detail 'Create a new article and associate with a profile' | |
289 | - params Noosfero::API::Entities::Article.documentation | |
290 | - success Noosfero::API::Entities::Article | |
291 | - failure [[403, 'Forbidden']] | |
292 | - named 'ArticleCreateToProfile' | |
293 | - end | |
294 | - post do | |
295 | - profile = environment.send(kind.pluralize).find(params["#{kind}_id"]) | |
296 | - post_article(profile, params) | |
297 | - end | |
298 | - end | |
299 | - end | |
300 | - end | |
301 | - end | |
302 | - end | |
303 | - end | |
304 | - end | |
305 | -end |
lib/noosfero/api/v1/blocks.rb
... | ... | @@ -1,17 +0,0 @@ |
1 | -module Noosfero | |
2 | - module API | |
3 | - module V1 | |
4 | - | |
5 | - class Blocks < Grape::API | |
6 | - resource :blocks do | |
7 | - get ':id' do | |
8 | - block = Block.find(params["id"]) | |
9 | - return forbidden! unless block.visible_to_user?(current_person) | |
10 | - present block, :with => Entities::Block, display_api_content: true | |
11 | - end | |
12 | - end | |
13 | - end | |
14 | - | |
15 | - end | |
16 | - end | |
17 | -end |
lib/noosfero/api/v1/boxes.rb
... | ... | @@ -1,46 +0,0 @@ |
1 | -module Noosfero | |
2 | - module API | |
3 | - module V1 | |
4 | - | |
5 | - class Boxes < Grape::API | |
6 | - | |
7 | - kinds = %w[profile community person enterprise] | |
8 | - kinds.each do |kind| | |
9 | - | |
10 | - resource kind.pluralize.to_sym do | |
11 | - | |
12 | - segment "/:#{kind}_id" do | |
13 | - resource :boxes do | |
14 | - get do | |
15 | - profile = environment.send(kind.pluralize).find(params["#{kind}_id"]) | |
16 | - present profile.boxes, :with => Entities::Box | |
17 | - end | |
18 | - end | |
19 | - end | |
20 | - end | |
21 | - | |
22 | - end | |
23 | - | |
24 | - resource :environments do | |
25 | - [ '/default', '/context', ':environment_id' ].each do |route| | |
26 | - segment route do | |
27 | - resource :boxes do | |
28 | - get do | |
29 | - if (route.match(/default/)) | |
30 | - env = Environment.default | |
31 | - elsif (route.match(/context/)) | |
32 | - env = environment | |
33 | - else | |
34 | - env = Environment.find(params[:environment_id]) | |
35 | - end | |
36 | - present env.boxes, :with => Entities::Box | |
37 | - end | |
38 | - end | |
39 | - end | |
40 | - end | |
41 | - end | |
42 | - end | |
43 | - | |
44 | - end | |
45 | - end | |
46 | -end |
lib/noosfero/api/v1/categories.rb
... | ... | @@ -1,27 +0,0 @@ |
1 | -module Noosfero | |
2 | - module API | |
3 | - module V1 | |
4 | - class Categories < Grape::API | |
5 | - | |
6 | - resource :categories do | |
7 | - | |
8 | - get do | |
9 | - type = params[:category_type] | |
10 | - include_parent = params[:include_parent] == 'true' | |
11 | - include_children = params[:include_children] == 'true' | |
12 | - | |
13 | - categories = type.nil? ? environment.categories : environment.categories.where(:type => type) | |
14 | - present categories, :with => Entities::Category, parent: include_parent, children: include_children | |
15 | - end | |
16 | - | |
17 | - desc "Return the category by id" | |
18 | - get ':id' do | |
19 | - present environment.categories.find(params[:id]), :with => Entities::Category, parent: true, children: true | |
20 | - end | |
21 | - | |
22 | - end | |
23 | - | |
24 | - end | |
25 | - end | |
26 | - end | |
27 | -end |
lib/noosfero/api/v1/comments.rb
... | ... | @@ -1,51 +0,0 @@ |
1 | -module Noosfero | |
2 | - module API | |
3 | - module V1 | |
4 | - class Comments < Grape::API | |
5 | - MAX_PER_PAGE = 20 | |
6 | - | |
7 | - | |
8 | - resource :articles do | |
9 | - paginate max_per_page: MAX_PER_PAGE | |
10 | - # Collect comments from articles | |
11 | - # | |
12 | - # Parameters: | |
13 | - # reference_id - comment id used as reference to collect comment | |
14 | - # oldest - Collect the oldest comments from reference_id comment. If nothing is passed the newest comments are collected | |
15 | - # limit - amount of comments returned. The default value is 20 | |
16 | - # | |
17 | - # Example Request: | |
18 | - # GET /articles/12/comments?oldest&limit=10&reference_id=23 | |
19 | - get ":id/comments" do | |
20 | - article = find_article(environment.articles, params[:id]) | |
21 | - comments = select_filtered_collection_of(article, :comments, params) | |
22 | - comments = comments.without_spam | |
23 | - comments = comments.without_reply if(params[:without_reply].present?) | |
24 | - comments = plugins.filter(:unavailable_comments, comments) | |
25 | - present paginate(comments), :with => Entities::Comment, :current_person => current_person | |
26 | - end | |
27 | - | |
28 | - get ":id/comments/:comment_id" do | |
29 | - article = find_article(environment.articles, params[:id]) | |
30 | - present article.comments.find(params[:comment_id]), :with => Entities::Comment, :current_person => current_person | |
31 | - end | |
32 | - | |
33 | - # Example Request: | |
34 | - # POST api/v1/articles/12/comments?private_token=2298743290432&body=new comment&title=New | |
35 | - post ":id/comments" do | |
36 | - authenticate! | |
37 | - article = find_article(environment.articles, params[:id]) | |
38 | - options = params.select { |key,v| !['id','private_token'].include?(key) }.merge(:author => current_person, :source => article) | |
39 | - begin | |
40 | - comment = Comment.create!(options) | |
41 | - rescue ActiveRecord::RecordInvalid => e | |
42 | - render_api_error!(e.message, 400) | |
43 | - end | |
44 | - present comment, :with => Entities::Comment, :current_person => current_person | |
45 | - end | |
46 | - end | |
47 | - | |
48 | - end | |
49 | - end | |
50 | - end | |
51 | -end |
lib/noosfero/api/v1/communities.rb
... | ... | @@ -1,84 +0,0 @@ |
1 | -module Noosfero | |
2 | - module API | |
3 | - module V1 | |
4 | - class Communities < Grape::API | |
5 | - | |
6 | - resource :communities do | |
7 | - | |
8 | - # Collect comments from articles | |
9 | - # | |
10 | - # Parameters: | |
11 | - # from - date where the search will begin. If nothing is passed the default date will be the date of the first article created | |
12 | - # oldest - Collect the oldest comments from reference_id comment. If nothing is passed the newest comments are collected | |
13 | - # limit - amount of comments returned. The default value is 20 | |
14 | - # | |
15 | - # Example Request: | |
16 | - # GET /communities?from=2013-04-04-14:41:43&until=2014-04-04-14:41:43&limit=10 | |
17 | - # GET /communities?reference_id=10&limit=10&oldest | |
18 | - get do | |
19 | - communities = select_filtered_collection_of(environment, 'communities', params) | |
20 | - communities = profiles_for_person(communities, current_person) | |
21 | - communities = communities.by_location(params) # Must be the last. May return Exception obj | |
22 | - present communities, :with => Entities::Community, :current_person => current_person | |
23 | - end | |
24 | - | |
25 | - | |
26 | - # Example Request: | |
27 | - # POST api/v1/communties?private_token=234298743290432&community[name]=some_name | |
28 | - # for each custom field for community, add &community[field_name]=field_value to the request | |
29 | - post do | |
30 | - authenticate! | |
31 | - params[:community] ||= {} | |
32 | - | |
33 | - params[:community][:custom_values]={} | |
34 | - params[:community].keys.each do |key| | |
35 | - params[:community][:custom_values][key]=params[:community].delete(key) if Community.custom_fields(environment).any?{|cf| cf.name==key} | |
36 | - end | |
37 | - | |
38 | - begin | |
39 | - community = Community.create_after_moderation(current_person, params[:community].merge({:environment => environment})) | |
40 | - rescue | |
41 | - community = Community.new(params[:community]) | |
42 | - end | |
43 | - | |
44 | - if !community.save | |
45 | - render_api_errors!(community.errors.full_messages) | |
46 | - end | |
47 | - | |
48 | - present community, :with => Entities::Community, :current_person => current_person | |
49 | - end | |
50 | - | |
51 | - get ':id' do | |
52 | - community = profiles_for_person(environment.communities, current_person).find_by_id(params[:id]) | |
53 | - present community, :with => Entities::Community, :current_person => current_person | |
54 | - end | |
55 | - | |
56 | - end | |
57 | - | |
58 | - resource :people do | |
59 | - | |
60 | - segment '/:person_id' do | |
61 | - | |
62 | - resource :communities do | |
63 | - | |
64 | - get do | |
65 | - person = environment.people.find(params[:person_id]) | |
66 | - | |
67 | - not_found! if person.blank? | |
68 | - forbidden! if !person.display_info_to?(current_person) | |
69 | - | |
70 | - communities = select_filtered_collection_of(person, 'communities', params) | |
71 | - communities = communities.visible | |
72 | - present communities, :with => Entities::Community, :current_person => current_person | |
73 | - end | |
74 | - | |
75 | - end | |
76 | - | |
77 | - end | |
78 | - | |
79 | - end | |
80 | - | |
81 | - end | |
82 | - end | |
83 | - end | |
84 | -end |
lib/noosfero/api/v1/contacts.rb
... | ... | @@ -1,28 +0,0 @@ |
1 | -module Noosfero | |
2 | - module API | |
3 | - module V1 | |
4 | - class Contacts < Grape::API | |
5 | - | |
6 | - resource :communities do | |
7 | - | |
8 | - resource ':id/contact' do | |
9 | - #contact => {:name => 'some name', :email => 'test@mail.com', :subject => 'some title', :message => 'some message'} | |
10 | - desc "Send a contact message" | |
11 | - post do | |
12 | - profile = environment.communities.find(params[:id]) | |
13 | - forbidden! unless profile.present? | |
14 | - contact = Contact.new params[:contact].merge(dest: profile) | |
15 | - if contact.deliver | |
16 | - {:success => true} | |
17 | - else | |
18 | - {:success => false} | |
19 | - end | |
20 | - end | |
21 | - | |
22 | - end | |
23 | - end | |
24 | - | |
25 | - end | |
26 | - end | |
27 | - end | |
28 | -end |
lib/noosfero/api/v1/enterprises.rb
... | ... | @@ -1,57 +0,0 @@ |
1 | -module Noosfero | |
2 | - module API | |
3 | - module V1 | |
4 | - class Enterprises < Grape::API | |
5 | - | |
6 | - resource :enterprises do | |
7 | - | |
8 | - # Collect enterprises from environment | |
9 | - # | |
10 | - # Parameters: | |
11 | - # from - date where the search will begin. If nothing is passed the default date will be the date of the first article created | |
12 | - # oldest - Collect the oldest comments from reference_id comment. If nothing is passed the newest comments are collected | |
13 | - # limit - amount of comments returned. The default value is 20 | |
14 | - # georef params - read `Profile.by_location` for more information. | |
15 | - # | |
16 | - # Example Request: | |
17 | - # GET /enterprises?from=2013-04-04-14:41:43&until=2014-04-04-14:41:43&limit=10 | |
18 | - # GET /enterprises?reference_id=10&limit=10&oldest | |
19 | - get do | |
20 | - enterprises = select_filtered_collection_of(environment, 'enterprises', params) | |
21 | - enterprises = enterprises.visible | |
22 | - enterprises = enterprises.by_location(params) # Must be the last. May return Exception obj. | |
23 | - present enterprises, :with => Entities::Enterprise, :current_person => current_person | |
24 | - end | |
25 | - | |
26 | - desc "Return one enterprise by id" | |
27 | - get ':id' do | |
28 | - enterprise = environment.enterprises.visible.find_by(id: params[:id]) | |
29 | - present enterprise, :with => Entities::Enterprise, :current_person => current_person | |
30 | - end | |
31 | - | |
32 | - end | |
33 | - | |
34 | - resource :people do | |
35 | - | |
36 | - segment '/:person_id' do | |
37 | - | |
38 | - resource :enterprises do | |
39 | - | |
40 | - get do | |
41 | - person = environment.people.find(params[:person_id]) | |
42 | - enterprises = select_filtered_collection_of(person, 'enterprises', params) | |
43 | - enterprises = enterprises.visible.by_location(params) | |
44 | - present enterprises, :with => Entities::Enterprise, :current_person => current_person | |
45 | - end | |
46 | - | |
47 | - end | |
48 | - | |
49 | - end | |
50 | - | |
51 | - end | |
52 | - | |
53 | - | |
54 | - end | |
55 | - end | |
56 | - end | |
57 | -end |
lib/noosfero/api/v1/environments.rb
... | ... | @@ -1,30 +0,0 @@ |
1 | -module Noosfero | |
2 | - module API | |
3 | - module V1 | |
4 | - class Environments < Grape::API | |
5 | - | |
6 | - resource :environment do | |
7 | - | |
8 | - desc "Return the person information" | |
9 | - get '/signup_person_fields' do | |
10 | - present environment.signup_person_fields | |
11 | - end | |
12 | - | |
13 | - get ':id' do | |
14 | - local_environment = nil | |
15 | - if (params[:id] == "default") | |
16 | - local_environment = Environment.default | |
17 | - elsif (params[:id] == "context") | |
18 | - local_environment = environment | |
19 | - else | |
20 | - local_environment = Environment.find(params[:id]) | |
21 | - end | |
22 | - present_partial local_environment, :with => Entities::Environment, :is_admin => is_admin?(local_environment) | |
23 | - end | |
24 | - | |
25 | - end | |
26 | - | |
27 | - end | |
28 | - end | |
29 | - end | |
30 | -end |
lib/noosfero/api/v1/people.rb
... | ... | @@ -1,129 +0,0 @@ |
1 | -module Noosfero | |
2 | - module API | |
3 | - module V1 | |
4 | - class People < Grape::API | |
5 | - | |
6 | - MAX_PER_PAGE = 50 | |
7 | - | |
8 | - desc 'API Root' | |
9 | - | |
10 | - resource :people do | |
11 | - paginate max_per_page: MAX_PER_PAGE | |
12 | - | |
13 | - # -- A note about privacy -- | |
14 | - # We wold find people by location, but we must test if the related | |
15 | - # fields are public. We can't do it now, with SQL, while the location | |
16 | - # data and the fields_privacy are a serialized settings. | |
17 | - # We must build a new table for profile data, where we can set meta-data | |
18 | - # like: | |
19 | - # | id | profile_id | key | value | privacy_level | source | | |
20 | - # | 1 | 99 | city | Salvador | friends | user | | |
21 | - # | 2 | 99 | lng | -38.521 | me only | automatic | | |
22 | - | |
23 | - # Collect people from environment | |
24 | - # | |
25 | - # Parameters: | |
26 | - # from - date where the search will begin. If nothing is passed the default date will be the date of the first article created | |
27 | - # oldest - Collect the oldest comments from reference_id comment. If nothing is passed the newest comments are collected | |
28 | - # limit - amount of comments returned. The default value is 20 | |
29 | - # | |
30 | - # Example Request: | |
31 | - # GET /people?from=2013-04-04-14:41:43&until=2014-04-04-14:41:43&limit=10 | |
32 | - # GET /people?reference_id=10&limit=10&oldest | |
33 | - | |
34 | - desc "Find environment's people" | |
35 | - get do | |
36 | - people = select_filtered_collection_of(environment, 'people', params) | |
37 | - people = people.visible | |
38 | - present_partial people, :with => Entities::Person, :current_person => current_person | |
39 | - end | |
40 | - | |
41 | - desc "Return the logged user information" | |
42 | - get "/me" do | |
43 | - authenticate! | |
44 | - present_partial current_person, :with => Entities::Person, :current_person => current_person | |
45 | - end | |
46 | - | |
47 | - desc "Return the person information" | |
48 | - get ':id' do | |
49 | - person = environment.people.visible.find_by(id: params[:id]) | |
50 | - return not_found! if person.blank? | |
51 | - present person, :with => Entities::Person, :current_person => current_person | |
52 | - end | |
53 | - | |
54 | - desc "Update person information" | |
55 | - post ':id' do | |
56 | - authenticate! | |
57 | - return forbidden! if current_person.id.to_s != params[:id] | |
58 | - current_person.update_attributes!(asset_with_image(params[:person])) | |
59 | - present current_person, :with => Entities::Person, :current_person => current_person | |
60 | - end | |
61 | - | |
62 | - # POST api/v1/people?person[login]=some_login&person[password]=some_password&person[name]=Jack | |
63 | - # for each custom field for person, add &person[field_name]=field_value to the request | |
64 | - desc "Create person" | |
65 | - post do | |
66 | - authenticate! | |
67 | - user_data = {} | |
68 | - user_data[:login] = params[:person].delete(:login) || params[:person][:identifier] | |
69 | - user_data[:email] = params[:person].delete(:email) | |
70 | - user_data[:password] = params[:person].delete(:password) | |
71 | - user_data[:password_confirmation] = params[:person].delete(:password_confirmation) | |
72 | - | |
73 | - params[:person][:custom_values]={} | |
74 | - params[:person].keys.each do |key| | |
75 | - params[:person][:custom_values][key]=params[:person].delete(key) if Person.custom_fields(environment).any?{|cf| cf.name==key} | |
76 | - end | |
77 | - | |
78 | - user = User.build(user_data, asset_with_image(params[:person]), environment) | |
79 | - | |
80 | - begin | |
81 | - user.signup! | |
82 | - rescue ActiveRecord::RecordInvalid | |
83 | - render_api_errors!(user.errors.full_messages) | |
84 | - end | |
85 | - | |
86 | - present user.person, :with => Entities::Person, :current_person => user.person | |
87 | - end | |
88 | - | |
89 | - desc "Return the person friends" | |
90 | - get ':id/friends' do | |
91 | - person = environment.people.visible.find_by(id: params[:id]) | |
92 | - return not_found! if person.blank? | |
93 | - friends = person.friends.visible | |
94 | - present friends, :with => Entities::Person, :current_person => current_person | |
95 | - end | |
96 | - | |
97 | - desc "Return the person permissions on other profiles" | |
98 | - get ":id/permissions" do | |
99 | - authenticate! | |
100 | - person = environment.people.find(params[:id]) | |
101 | - return not_found! if person.blank? | |
102 | - return forbidden! unless current_person == person || environment.admins.include?(current_person) | |
103 | - | |
104 | - output = {} | |
105 | - person.role_assignments.map do |role_assigment| | |
106 | - if role_assigment.resource.respond_to?(:identifier) | |
107 | - output[role_assigment.resource.identifier] = role_assigment.role.permissions | |
108 | - end | |
109 | - end | |
110 | - present output | |
111 | - end | |
112 | - end | |
113 | - | |
114 | - resource :profiles do | |
115 | - segment '/:profile_id' do | |
116 | - resource :members do | |
117 | - paginate max_per_page: MAX_PER_PAGE | |
118 | - get do | |
119 | - profile = environment.profiles.find_by id: params[:profile_id] | |
120 | - members = select_filtered_collection_of(profile, 'members', params) | |
121 | - present members, :with => Entities::Person, :current_person => current_person | |
122 | - end | |
123 | - end | |
124 | - end | |
125 | - end | |
126 | - end | |
127 | - end | |
128 | - end | |
129 | -end |
lib/noosfero/api/v1/profiles.rb
... | ... | @@ -1,44 +0,0 @@ |
1 | -module Noosfero | |
2 | - module API | |
3 | - module V1 | |
4 | - class Profiles < Grape::API | |
5 | - | |
6 | - resource :profiles do | |
7 | - | |
8 | - get do | |
9 | - profiles = select_filtered_collection_of(environment, 'profiles', params) | |
10 | - profiles = profiles.visible | |
11 | - profiles = profiles.by_location(params) # Must be the last. May return Exception obj. | |
12 | - present profiles, :with => Entities::Profile, :current_person => current_person | |
13 | - end | |
14 | - | |
15 | - get ':id' do | |
16 | - profiles = environment.profiles | |
17 | - profiles = profiles.visible | |
18 | - profile = profiles.find_by id: params[:id] | |
19 | - | |
20 | - if profile | |
21 | - present profile, :with => Entities::Profile, :current_person => current_person | |
22 | - else | |
23 | - not_found! | |
24 | - end | |
25 | - end | |
26 | - | |
27 | - delete ':id' do | |
28 | - authenticate! | |
29 | - profiles = environment.profiles | |
30 | - profile = profiles.find_by id: params[:id] | |
31 | - | |
32 | - not_found! if profile.blank? | |
33 | - | |
34 | - if current_person.has_permission?(:destroy_profile, profile) | |
35 | - profile.destroy | |
36 | - else | |
37 | - forbidden! | |
38 | - end | |
39 | - end | |
40 | - end | |
41 | - end | |
42 | - end | |
43 | - end | |
44 | -end |
lib/noosfero/api/v1/search.rb
... | ... | @@ -1,39 +0,0 @@ |
1 | -module Noosfero | |
2 | - module API | |
3 | - module V1 | |
4 | - class Search < Grape::API | |
5 | - | |
6 | - resource :search do | |
7 | - resource :article do | |
8 | - paginate max_per_page: 200 | |
9 | - get do | |
10 | - # Security checks | |
11 | - sanitize_params_hash(params) | |
12 | - # APIHelpers | |
13 | - asset = :articles | |
14 | - context = environment | |
15 | - | |
16 | - profile = environment.profiles.find(params[:profile_id]) if params[:profile_id] | |
17 | - scope = profile.nil? ? environment.articles.is_public : profile.articles.is_public | |
18 | - scope = scope.where(:type => params[:type]) if params[:type] && !(params[:type] == 'Article') | |
19 | - scope = scope.where(make_conditions_with_parameter(params)) | |
20 | - scope = scope.joins(:categories).where(:categories => {:id => params[:category_ids]}) if params[:category_ids].present? | |
21 | - scope = scope.where('articles.children_count > 0') if params[:has_children].present? | |
22 | - query = params[:query] || "" | |
23 | - order = "more_recent" | |
24 | - | |
25 | - options = {:filter => order, :template_id => params[:template_id]} | |
26 | - | |
27 | - search_result = find_by_contents(asset, context, scope, query, {:page => 1}, options) | |
28 | - | |
29 | - articles = search_result[:results] | |
30 | - | |
31 | - present_articles(articles) | |
32 | - end | |
33 | - end | |
34 | - end | |
35 | - | |
36 | - end | |
37 | - end | |
38 | - end | |
39 | -end |
lib/noosfero/api/v1/tags.rb
... | ... | @@ -1,32 +0,0 @@ |
1 | -module Noosfero | |
2 | - module API | |
3 | - module V1 | |
4 | - class Tags < Grape::API | |
5 | - resource :articles do | |
6 | - resource ':id/tags' do | |
7 | - get do | |
8 | - article = find_article(environment.articles, params[:id]) | |
9 | - present article.tag_list | |
10 | - end | |
11 | - | |
12 | - desc "Add a tag to an article" | |
13 | - post do | |
14 | - authenticate! | |
15 | - article = find_article(environment.articles, params[:id]) | |
16 | - article.tag_list=params[:tags] | |
17 | - article.save | |
18 | - present article.tag_list | |
19 | - end | |
20 | - end | |
21 | - end | |
22 | - | |
23 | - resource :environment do | |
24 | - desc 'Return the tag counts for this environment' | |
25 | - get '/tags' do | |
26 | - present environment.tag_counts | |
27 | - end | |
28 | - end | |
29 | - end | |
30 | - end | |
31 | - end | |
32 | -end |
lib/noosfero/api/v1/tasks.rb
... | ... | @@ -1,59 +0,0 @@ |
1 | -module Noosfero | |
2 | - module API | |
3 | - module V1 | |
4 | - class Tasks < Grape::API | |
5 | -# before { authenticate! } | |
6 | - | |
7 | -# ARTICLE_TYPES = Article.descendants.map{|a| a.to_s} | |
8 | - | |
9 | - resource :tasks do | |
10 | - | |
11 | - # Collect tasks | |
12 | - # | |
13 | - # Parameters: | |
14 | - # from - date where the search will begin. If nothing is passed the default date will be the date of the first article created | |
15 | - # oldest - Collect the oldest articles. If nothing is passed the newest articles are collected | |
16 | - # limit - amount of articles returned. The default value is 20 | |
17 | - # | |
18 | - # Example Request: | |
19 | - # GET host/api/v1/tasks?from=2013-04-04-14:41:43&until=2015-04-04-14:41:43&limit=10&private_token=e96fff37c2238fdab074d1dcea8e6317 | |
20 | - get do | |
21 | - tasks = select_filtered_collection_of(environment, 'tasks', params) | |
22 | - tasks = tasks.select {|t| current_person.has_permission?(t.permission, environment)} | |
23 | - present_partial tasks, :with => Entities::Task | |
24 | - end | |
25 | - | |
26 | - desc "Return the task id" | |
27 | - get ':id' do | |
28 | - task = find_task(environment, params[:id]) | |
29 | - present_partial task, :with => Entities::Task | |
30 | - end | |
31 | - end | |
32 | - | |
33 | - kinds = %w[community person enterprise] | |
34 | - kinds.each do |kind| | |
35 | - resource kind.pluralize.to_sym do | |
36 | - segment "/:#{kind}_id" do | |
37 | - resource :tasks do | |
38 | - get do | |
39 | - profile = environment.send(kind.pluralize).find(params["#{kind}_id"]) | |
40 | - present_tasks(profile) | |
41 | - end | |
42 | - | |
43 | - get ':id' do | |
44 | - profile = environment.send(kind.pluralize).find(params["#{kind}_id"]) | |
45 | - present_task(profile) | |
46 | - end | |
47 | - | |
48 | - post do | |
49 | - profile = environment.send(kind.pluralize).find(params["#{kind}_id"]) | |
50 | - post_task(profile, params) | |
51 | - end | |
52 | - end | |
53 | - end | |
54 | - end | |
55 | - end | |
56 | - end | |
57 | - end | |
58 | - end | |
59 | -end |
lib/noosfero/api/v1/users.rb
... | ... | @@ -1,45 +0,0 @@ |
1 | -module Noosfero | |
2 | - module API | |
3 | - module V1 | |
4 | - class Users < Grape::API | |
5 | - | |
6 | - resource :users do | |
7 | - | |
8 | - get do | |
9 | - users = select_filtered_collection_of(environment, 'users', params) | |
10 | - users = users.select{|u| u.person.display_info_to? current_person} | |
11 | - present users, :with => Entities::User, :current_person => current_person | |
12 | - end | |
13 | - | |
14 | - get "/me" do | |
15 | - authenticate! | |
16 | - present current_user, :with => Entities::User, :current_person => current_person | |
17 | - end | |
18 | - | |
19 | - get ":id" do | |
20 | - user = environment.users.find_by id: params[:id] | |
21 | - if user | |
22 | - present user, :with => Entities::User, :current_person => current_person | |
23 | - else | |
24 | - not_found! | |
25 | - end | |
26 | - end | |
27 | - | |
28 | - get ":id/permissions" do | |
29 | - authenticate! | |
30 | - user = environment.users.find(params[:id]) | |
31 | - output = {} | |
32 | - user.person.role_assignments.map do |role_assigment| | |
33 | - if role_assigment.resource.respond_to?(:identifier) && role_assigment.resource.identifier == params[:profile] | |
34 | - output[:permissions] = role_assigment.role.permissions | |
35 | - end | |
36 | - end | |
37 | - present output | |
38 | - end | |
39 | - | |
40 | - end | |
41 | - | |
42 | - end | |
43 | - end | |
44 | - end | |
45 | -end |
lib/noosfero/core_ext.rb
lib/noosfero/core_ext/active_record/calculations.rb
lib/noosfero/core_ext/active_record/reflection.rb
... | ... | @@ -1,20 +0,0 @@ |
1 | - | |
2 | -# on STI classes tike Article and Profile, plugins' extensions | |
3 | -# on associations should be reflected on descendants | |
4 | -module ActiveRecord | |
5 | - module Reflection | |
6 | - | |
7 | - class << self | |
8 | - | |
9 | - def add_reflection_with_descendants(ar, name, reflection) | |
10 | - self.add_reflection_without_descendants ar, name, reflection | |
11 | - ar.descendants.each do |k| | |
12 | - k._reflections.merge!(name.to_s => reflection) | |
13 | - end if ar.base_class == ar | |
14 | - end | |
15 | - | |
16 | - alias_method_chain :add_reflection, :descendants | |
17 | - | |
18 | - end | |
19 | - end | |
20 | -end |
lib/noosfero/core_ext/integer.rb
... | ... | @@ -1,39 +0,0 @@ |
1 | -class Integer | |
2 | - def to_humanreadable | |
3 | - value = self | |
4 | - if value < 1023 | |
5 | - return "%i bytes" % value | |
6 | - end | |
7 | - value /= 1024 | |
8 | - | |
9 | - if value < 1023 | |
10 | - return "%1.1f KB" % value | |
11 | - end | |
12 | - value /= 1024 | |
13 | - | |
14 | - if value < 1023 | |
15 | - return "%1.1f MB" % value | |
16 | - end | |
17 | - value /= 1024 | |
18 | - | |
19 | - if value < 1023 | |
20 | - return "%1.1f GB" % value | |
21 | - end | |
22 | - value /= 1024 | |
23 | - | |
24 | - if value < 1023 | |
25 | - return "%1.1f TB" % value | |
26 | - end | |
27 | - value /= 1024 | |
28 | - | |
29 | - if value < 1023 | |
30 | - return "%1.1f PB" % value | |
31 | - end | |
32 | - value /= 1024 | |
33 | - | |
34 | - if value < 1023 | |
35 | - return "%1.1f EB" % value | |
36 | - end | |
37 | - value /= 1024 | |
38 | - end | |
39 | -end |
lib/noosfero/core_ext/string.rb
... | ... | @@ -1,93 +0,0 @@ |
1 | -# encoding: utf-8 | |
2 | - | |
3 | -class String | |
4 | - | |
5 | - TRANSLITERATIONS = { | |
6 | - [ 'Á', 'À', 'À', 'Â', 'Ã', 'Ä', 'Å' ] => 'A', | |
7 | - [ 'á', 'à', 'à', 'â', 'ã', 'ä', 'å' ,'ª' ] => 'a', | |
8 | - [ 'É', 'È', 'Ê', 'Ë' ] => 'E', | |
9 | - [ 'é', 'è', 'ê', 'ë' ] => 'e', | |
10 | - [ 'Í', 'Ì', 'Î', 'Ï' ] => 'I', | |
11 | - [ 'í', 'ì', 'î', 'ï' ] => 'i', | |
12 | - [ 'Ó', 'Ò', 'Ô', 'Ö', 'Õ', 'º' ] => 'O', | |
13 | - [ 'ó', 'ò', 'ô', 'ö', 'õ', 'º' ] => 'o', | |
14 | - [ 'Ú', 'Ù', 'Û', 'Ü' ] => 'U', | |
15 | - [ 'ú', 'ù', 'û', 'ü' ] => 'u', | |
16 | - [ 'ß' ] => 'ss', | |
17 | - [ 'Ç' ] => 'C', | |
18 | - [ 'ç' ] => 'c', | |
19 | - [ 'Ñ' ] => 'N', | |
20 | - [ 'ñ' ] => 'n', | |
21 | - [ 'Ÿ' ] => 'Y', | |
22 | - [ 'ÿ' ] => 'y', | |
23 | -# Cyrillic alphabet transliteration | |
24 | - [ 'а', 'А' ] => 'a', | |
25 | - [ 'б', 'Б' ] => 'b', | |
26 | - [ 'в', 'В' ] => 'v', | |
27 | - [ 'г', 'Г' ] => 'g', | |
28 | - [ 'д', 'Д' ] => 'd', | |
29 | - [ 'е', 'Е' ] => 'e', | |
30 | - [ 'ё', 'Ё' ] => 'yo', | |
31 | - [ 'ж', 'Ж' ] => 'zh', | |
32 | - [ 'з', 'З' ] => 'z', | |
33 | - [ 'и', 'И' ] => 'i', | |
34 | - [ 'й', 'Й' ] => 'y', | |
35 | - [ 'к', 'К' ] => 'k', | |
36 | - [ 'л', 'Л' ] => 'l', | |
37 | - [ 'м', 'М' ] => 'm', | |
38 | - [ 'н', 'Н' ] => 'n', | |
39 | - [ 'о', 'О' ] => 'o', | |
40 | - [ 'п', 'П' ] => 'p', | |
41 | - [ 'р', 'Р' ] => 'r', | |
42 | - [ 'с', 'С' ] => 's', | |
43 | - [ 'т', 'Т' ] => 't', | |
44 | - [ 'у', 'У' ] => 'u', | |
45 | - [ 'ф', 'Ф' ] => 'f', | |
46 | - [ 'х', 'Х' ] => 'h', | |
47 | - [ 'ц', 'Ц' ] => 'ts', | |
48 | - [ 'ч', 'Ч' ] => 'ch', | |
49 | - [ 'ш', 'Ш' ] => 'sh', | |
50 | - [ 'щ', 'Щ' ] => 'sch', | |
51 | - [ 'э', 'Э' ] => 'e', | |
52 | - [ 'ю', 'Ю' ] => 'yu', | |
53 | - [ 'я', 'Я' ] => 'ya', | |
54 | - [ 'ы', 'Ы' ] => 'i', | |
55 | - [ 'ь', 'Ь' ] => '', | |
56 | - [ 'ъ', 'Ъ' ] => '', | |
57 | -# Ukrainian lovely letters | |
58 | - [ 'і', 'І' ] => 'i', | |
59 | - [ 'ї', 'Ї' ] => 'yi', | |
60 | - [ 'є', 'Є' ] => 'ye', | |
61 | - [ 'ґ', 'Ґ' ] => 'g', | |
62 | - } | |
63 | - | |
64 | - # transliterate a string (assumed to contain UTF-8 data) | |
65 | - # into ASCII by replacing non-ascii characters to their | |
66 | - # ASCII. | |
67 | - # | |
68 | - # The transliteration is, of course, lossy, and its performance is poor. | |
69 | - # Don't abuse this method. | |
70 | - def transliterate | |
71 | - | |
72 | - new = self.dup | |
73 | - TRANSLITERATIONS.each { |from,to| | |
74 | - from.each { |seq| | |
75 | - new.gsub!(seq, to) | |
76 | - } | |
77 | - } | |
78 | - new | |
79 | - end | |
80 | - | |
81 | - def to_slug | |
82 | - transliterate.downcase.gsub(/[^[[:word:]]~\s:;+=_."'`-]/, '').gsub(/[\s:;+=_"'`-]+/, '-').gsub(/-$/, '').gsub(/^-/, '').to_s | |
83 | - end | |
84 | - | |
85 | - def to_css_class | |
86 | - underscore.dasherize.gsub('/','_') | |
87 | - end | |
88 | - | |
89 | - def fix_i18n | |
90 | - self.sub('{fn} ', '') | |
91 | - end | |
92 | - | |
93 | -end |
lib/noosfero/multi_tenancy.rb
... | ... | @@ -12,14 +12,13 @@ module Noosfero |
12 | 12 | def self.db_by_host=(host) |
13 | 13 | if host != @db_by_host |
14 | 14 | @db_by_host = host |
15 | - ApplicationRecord.connection.schema_search_path = self.mapping[host] | |
15 | + ActiveRecord::Base.connection.schema_search_path = self.mapping[host] | |
16 | 16 | end |
17 | 17 | end |
18 | 18 | |
19 | 19 | def self.setup!(host) |
20 | - if Noosfero::MultiTenancy.on? and ApplicationRecord.postgresql? | |
21 | - Noosfero::MultiTenancy.db_by_host = host | |
22 | - end | |
20 | + return unless Noosfero::MultiTenancy.on? | |
21 | + Noosfero::MultiTenancy.db_by_host = host | |
23 | 22 | end |
24 | 23 | |
25 | 24 | class Middleware | ... | ... |
lib/noosfero/unicorn.rb
... | ... | @@ -7,11 +7,11 @@ GC.respond_to?(:copy_on_write_friendly=) and |
7 | 7 | GC.copy_on_write_friendly = true |
8 | 8 | |
9 | 9 | before_fork do |server, worker| |
10 | - ApplicationRecord.connection.disconnect! if defined?(ApplicationRecord) | |
10 | + ActiveRecord::Base.connection.disconnect! if defined? ActiveRecord::Base | |
11 | 11 | end |
12 | 12 | |
13 | 13 | after_fork do |server, worker| |
14 | - ApplicationRecord.establish_connection if defined?(ApplicationRecord) | |
14 | + ActiveRecord::Base.establish_connection if defined? ActiveRecord::Base | |
15 | 15 | end |
16 | 16 | |
17 | 17 | # load local configuration file, if it exists | ... | ... |
lib/postgresql_attachment_fu.rb
... | ... | @@ -9,12 +9,12 @@ module PostgresqlAttachmentFu |
9 | 9 | module InstanceMethods |
10 | 10 | def full_filename(thumbnail = nil) |
11 | 11 | file_system_path = (thumbnail ? thumbnail_class : self).attachment_options[:path_prefix].to_s |
12 | - file_system_path = File.join(file_system_path, ApplicationRecord.connection.schema_search_path) if ApplicationRecord.postgresql? and Noosfero::MultiTenancy.on? | |
12 | + file_system_path = File.join(file_system_path, ActiveRecord::Base.connection.schema_search_path) if Noosfero::MultiTenancy.on? | |
13 | 13 | Rails.root.join(file_system_path, *partitioned_path(thumbnail_name_for(thumbnail))).to_s |
14 | 14 | end |
15 | 15 | end |
16 | 16 | |
17 | 17 | end |
18 | 18 | |
19 | -ApplicationRecord.extend PostgresqlAttachmentFu::ClassMethods | |
19 | +ActiveRecord::Base.extend PostgresqlAttachmentFu::ClassMethods | |
20 | 20 | ... | ... |
lib/split_datetime.rb
lib/sqlite_extension.rb
... | ... | @@ -1,28 +0,0 @@ |
1 | -if ApplicationRecord.connection.adapter_name.downcase == 'sqlite' | |
2 | - | |
3 | - database = ApplicationRecord.connection.raw_connection | |
4 | - | |
5 | - database.create_function('pow', 2, 1) do |func, base, exponent| | |
6 | - func.set_result(base.to_f ** exponent.to_f) | |
7 | - end | |
8 | - | |
9 | - database.create_function('sqrt', 1, 1) do |func, value| | |
10 | - func.set_result(Math.sqrt(value)) | |
11 | - end | |
12 | - | |
13 | - database.create_function('radians', 1, 1) do |func, value| | |
14 | - func.set_result(value.to_f * Math::PI / 180.0) | |
15 | - end | |
16 | - | |
17 | - database.create_function('spheric_distance', 5, 1) do |func, lat1, long1, lat2, long2, radius| | |
18 | - func.set_result( | |
19 | - radius.to_f * Math.acos( | |
20 | - [1, | |
21 | - Math.cos(lat1.to_f) * Math.cos(long1.to_f) * Math.cos(lat2.to_f) * Math.cos(long2.to_f) + | |
22 | - Math.cos(lat1.to_f) * Math.sin(long1.to_f) * Math.cos(lat2.to_f) * Math.sin(long2.to_f) + | |
23 | - Math.sin(lat1.to_f) * Math.sin(lat2.to_f) | |
24 | - ].min | |
25 | - ) | |
26 | - ) | |
27 | - end | |
28 | -end |
lib/tasks/backup.rake
... | ... | @@ -115,7 +115,7 @@ end |
115 | 115 | |
116 | 116 | desc 'Removes emails from database' |
117 | 117 | task 'restore:remove_emails' => :environment do |
118 | - connection = ApplicationRecord.connection | |
118 | + connection = ActiveRecord::Base.connection | |
119 | 119 | [ |
120 | 120 | "UPDATE users SET email = concat('user', id, '@localhost.localdomain')", |
121 | 121 | "UPDATE environments SET contact_email = concat('environment', id, '@localhost.localdomain')", | ... | ... |
lib/tasks/grape_routes.rb
lib/tasks/multitenancy.rake
1 | 1 | namespace :multitenancy do |
2 | 2 | |
3 | 3 | task :create => :environment do |
4 | - db_envs = ApplicationRecord.configurations.keys.select{ |k| k.match(/_development$|_production$|_test$/) } | |
4 | + db_envs = ActiveRecord::Base.configurations.keys.select{ |k| k.match(/_development$|_production$|_test$/) } | |
5 | 5 | cd Rails.root.join('config', 'environments'), :verbose => true |
6 | 6 | file_envs = Dir.glob "{*_development.rb,*_production.rb,*_test.rb}" |
7 | 7 | (db_envs.map{ |e| e + '.rb' } - file_envs).each { |env| ln_s env.split('_').last, env } |
8 | 8 | end |
9 | 9 | |
10 | 10 | task :remove => :environment do |
11 | - db_envs = ApplicationRecord.configurations.keys.select{ |k| k.match(/_development$|_production$|_test$/) } | |
11 | + db_envs = ActiveRecord::Base.configurations.keys.select{ |k| k.match(/_development$|_production$|_test$/) } | |
12 | 12 | cd Rails.root.join('config', 'environments'), :verbose => true |
13 | 13 | file_envs = Dir.glob "{*_development.rb,*_production.rb,*_test.rb}" |
14 | 14 | (file_envs - db_envs.map{ |e| e + '.rb' }).each { |env| safe_unlink env } |
... | ... | @@ -19,7 +19,7 @@ end |
19 | 19 | namespace :db do |
20 | 20 | |
21 | 21 | task :migrate_other_environments => :environment do |
22 | - envs = ApplicationRecord.configurations.keys.select{ |k| k.match(/_#{Rails.env}$/) } | |
22 | + envs = ActiveRecord::Base.configurations.keys.select{ |k| k.match(/_#{Rails.env}$/) } | |
23 | 23 | envs.each do |e| |
24 | 24 | puts "*** Migrating #{e}" if Rake.application.options.trace |
25 | 25 | system "rake db:migrate RAILS_ENV=#{e} SCHEMA=/dev/null" | ... | ... |
lib/upload_sanitizer.rb
plugins/admin_notifications/lib/admin_notifications_plugin/notifications_user.rb
plugins/admin_notifications/models/admin_notifications_plugin/notification.rb
plugins/admin_notifications/views/admin_notifications_plugin_public/notifications_with_popup.html.erb
... | ... | @@ -9,12 +9,12 @@ |
9 | 9 | </div> |
10 | 10 | </div> |
11 | 11 | <div class="notification-message notification-with-title-message"> |
12 | - <%= AdminNotificationsPlugin::NotificationHelper.substitute_variables(notification.message, current_user) %> | |
12 | + <%= AdminNotificationsPlugin::NotificationHelper.substitute_variables(notification.message, current_user).html_safe %> | |
13 | 13 | </div> |
14 | 14 | <% else %> |
15 | 15 | <div class="<%= notification.type.gsub("AdminNotificationsPlugin::", "").downcase %> notification notification-without-title" data-notification="<%=notification.id%>"> |
16 | 16 | <div class="notification-message"> |
17 | - <%= AdminNotificationsPlugin::NotificationHelper.substitute_variables(notification.message, current_user) %> | |
17 | + <%= AdminNotificationsPlugin::NotificationHelper.substitute_variables(notification.message, current_user).html_safe %> | |
18 | 18 | </div> |
19 | 19 | </div> |
20 | 20 | <% end %> | ... | ... |
plugins/admin_notifications/views/shared/_notifications_list.html.erb
... | ... | @@ -23,7 +23,7 @@ |
23 | 23 | <% @notifications.each do |notification| %> |
24 | 24 | <div class="notification-line"> |
25 | 25 | <div class="notification-message"> |
26 | - <%= truncate(notification.message, length: 50) %> | |
26 | + <%= truncate(notification.message.html_safe, length: 50) %> | |
27 | 27 | </div> |
28 | 28 | <div class="notification-action"> |
29 | 29 | <% if notification.active? %> | ... | ... |
plugins/admin_notifications/views/shared/show_notification.html.erb
... | ... | @@ -22,7 +22,7 @@ |
22 | 22 | <% @notifications.each do |notification| %> |
23 | 23 | <div class="<%= notification.type.gsub("AdminNotificationsPlugin::", "").downcase %> notification" data-notification="<%=notification.id%>" notification-display-popup="<%=notification.display_popup?%>"> |
24 | 24 | <div class="notification-message"> |
25 | - <%= AdminNotificationsPlugin::NotificationHelper.substitute_variables(notification.message, current_user) %> | |
25 | + <%= AdminNotificationsPlugin::NotificationHelper.substitute_variables(notification.message, current_user).html_safe %> | |
26 | 26 | </div> |
27 | 27 | <% if logged_in? %> |
28 | 28 | <div class="notification-close" title="<%= _('Do not show anymore') %>"></div> | ... | ... |
plugins/breadcrumbs/lib/breadcrumbs_plugin/content_breadcrumbs_block.rb
... | ... | @@ -22,70 +22,8 @@ class BreadcrumbsPlugin::ContentBreadcrumbsBlock < Block |
22 | 22 | _('This block displays breadcrumb trail.') |
23 | 23 | end |
24 | 24 | |
25 | - def page_trail(page, params={}) | |
26 | - links = [] | |
27 | - if page | |
28 | - links = page.ancestors.reverse.map { |p| { :name => p.title, :url => p.url } } | |
29 | - links << { :name => page.title, :url => page.url } | |
30 | - elsif params[:controller] == 'cms' | |
31 | - id = params[:id] || params[:parent_id] | |
32 | - links = page_trail(Article.find(id)) if id | |
33 | - links << { :name => cms_action(params[:action]), :url => params } if show_cms_action | |
34 | - elsif (params[:controller] == 'profile' || params[:controller] == 'events') | |
35 | - links << { :name => _('Profile'), :url => {:controller=> 'profile', :action =>'index', :profile =>params[:profile]}} | |
36 | - links << { :name => profile_action(params[:action]), :url => params } unless params[:action] == 'index' | |
37 | - end | |
38 | - links | |
39 | - end | |
40 | - | |
41 | - def trail(page, profile=nil, params={}) | |
42 | - links = page_trail(page, params) | |
43 | - if profile && !links.empty? && show_profile | |
44 | - [ {:name => profile.name, :url => profile.url} ] + links | |
45 | - else | |
46 | - links | |
47 | - end | |
48 | - end | |
49 | - | |
50 | - def content(args={}) | |
51 | - block = self | |
52 | - ret = (proc do | |
53 | - trail = block.trail(@page, @profile, params) | |
54 | - if !trail.empty? | |
55 | - separator = content_tag('span', ' > ', :class => 'separator') | |
56 | - | |
57 | - breadcrumb = trail.map do |t| | |
58 | - link_to(t[:name], t[:url], :class => 'item') | |
59 | - end.join(separator) | |
60 | - | |
61 | - if block.show_section_name | |
62 | - section_name = block.show_profile ? trail.second[:name] : trail.first[:name] | |
63 | - breadcrumb << content_tag('div', section_name, :class => 'section-name') | |
64 | - end | |
65 | - | |
66 | - breadcrumb.html_safe | |
67 | - else | |
68 | - '' | |
69 | - end | |
70 | - end) | |
71 | - ret | |
72 | - end | |
73 | - | |
74 | 25 | def cacheable? |
75 | 26 | false |
76 | 27 | end |
77 | 28 | |
78 | - protected | |
79 | - | |
80 | - CMS_ACTIONS = {:edit => c_('Edit'), :upload_files => _('Upload Files'), :new => c_('New')} | |
81 | - PROFILE_ACTIONS = {:members => _('Members'), :events => _('Events')} | |
82 | - | |
83 | - def cms_action(action) | |
84 | - CMS_ACTIONS[action.to_sym] || action | |
85 | - end | |
86 | - | |
87 | - def profile_action(action) | |
88 | - PROFILE_ACTIONS[action.to_sym] || action | |
89 | - end | |
90 | - | |
91 | 29 | end | ... | ... |
... | ... | @@ -0,0 +1,43 @@ |
1 | +module BreadcrumbsPluginHelper | |
2 | + | |
3 | + def action(action) | |
4 | + { :edit => c_('Edit'), | |
5 | + :upload_files => _('Upload Files'), | |
6 | + :new => c_('New'), | |
7 | + :members => _('Members'), | |
8 | + :events => _('Events') | |
9 | + }[action.to_sym] || action | |
10 | + end | |
11 | + | |
12 | + def page_trail(page) | |
13 | + links = [] | |
14 | + page.ancestors.reverse.each do |p| | |
15 | + links << { :name => p.title, :url => p.url } | |
16 | + end | |
17 | + links << { :name => page.title, :url => page.url } | |
18 | + links | |
19 | + end | |
20 | + | |
21 | + def trail(block, page, profile=nil, params={}) | |
22 | + links = [] | |
23 | + if page | |
24 | + links += page_trail(page) | |
25 | + elsif params[:controller] == 'cms' && (id = params[:id] || params[:parent_id]) | |
26 | + links += page_trail(Article.find(id)) | |
27 | + if block.show_cms_action | |
28 | + links << { :name => action(params[:action]), :url => params } | |
29 | + end | |
30 | + elsif (params[:controller] == 'profile' || params[:controller] == 'events') | |
31 | + _params = {:controller=> 'profile', :action =>'index', :profile => params[:profile]} | |
32 | + links << { :name => _('Profile'), :url => _params } | |
33 | + unless params[:action] == 'index' | |
34 | + links << { :name => action(params[:action]), :url => params } | |
35 | + end | |
36 | + end | |
37 | + if !links.empty? && profile && block.show_profile | |
38 | + links.unshift({:name => profile.name, :url => profile.url}) | |
39 | + end | |
40 | + links | |
41 | + end | |
42 | + | |
43 | +end | ... | ... |
plugins/breadcrumbs/test/unit/breadcrumbs_plugin_helper_test.rb
0 → 100644
... | ... | @@ -0,0 +1,66 @@ |
1 | +require 'test_helper' | |
2 | + | |
3 | +class BreadcrumbsPluginHelperTest < ActionView::TestCase | |
4 | + include BreadcrumbsPluginHelper | |
5 | + | |
6 | + def setup | |
7 | + @block = BreadcrumbsPlugin::ContentBreadcrumbsBlock.new | |
8 | + @profile = fast_create(Community) | |
9 | + @folder = fast_create(Folder, :profile_id => @profile.id) | |
10 | + @article = fast_create(Folder, :profile_id => @profile.id, :parent_id => @folder.id) | |
11 | + @params = {} | |
12 | + end | |
13 | + | |
14 | + attr_reader :params | |
15 | + | |
16 | + should 'return path of links to reach a page' do | |
17 | + links = [{:name => @folder.name, :url => @folder.url}, {:name => @article.name, :url => @article.url}] | |
18 | + assert_equal links, page_trail(@article) | |
19 | + end | |
20 | + | |
21 | + should 'return path of links when current page is at cms controller' do | |
22 | + params = {:controller => 'cms', :action => 'edit', :id => @article.id} | |
23 | + links = [{:name => @folder.name, :url => @folder.url}, {:name => @article.name, :url => @article.url}, {:url=>params, :name=>"Edit"}] | |
24 | + assert_equal links, trail(@block, nil, nil, params) | |
25 | + end | |
26 | + | |
27 | + should 'not return cms action link when show_cms_action is false' do | |
28 | + params = {:controller => 'cms', :action => 'edit', :id => @article.id} | |
29 | + links = [{:name => @folder.name, :url => @folder.url}, {:name => @article.name, :url => @article.url}] | |
30 | + @block.show_cms_action = false | |
31 | + assert_equal links, trail(@block, nil, nil, params) | |
32 | + end | |
33 | + | |
34 | + should 'include profile page link on path of links to reach a profile controller page' do | |
35 | + params = {:controller => 'profile', :action => 'members', :profile => @profile.identifier} | |
36 | + links = [{:name => 'Profile', :url => {:controller => 'profile', :action => 'index', :profile => @profile.identifier}}, {:name => 'Members', :url => {:controller=>'profile', :action=>'members', :profile=> @profile.identifier}}] | |
37 | + assert_equal links, trail(@block, nil, nil, params) | |
38 | + end | |
39 | + | |
40 | + should 'include only the profile page link on path links when profile action is index' do | |
41 | + params = {:controller => 'profile', :action => 'index', :profile => @profile.identifier} | |
42 | + links = [{:name => 'Profile', :url => {:controller => 'profile', :action => 'index', :profile => @profile.identifier}}] | |
43 | + assert_equal links, trail(@block, nil, nil, params) | |
44 | + end | |
45 | + | |
46 | + should 'profile page be the ancestor page of event profile page calendar' do | |
47 | + params = {:controller => 'profile', :action => 'events', :profile => @profile.identifier} | |
48 | + links = [{:name => 'Profile', :url => {:controller => 'profile', :action => 'index', :profile => @profile.identifier}}, {:name => 'Events', :url => {:controller=>'profile', :action=>'events', :profile=> @profile.identifier}}] | |
49 | + assert_equal links, trail(@block, nil, nil, params) | |
50 | + end | |
51 | + | |
52 | + should 'include profile link on path of links to reach a page' do | |
53 | + links = [{:name => @profile.name, :url => @profile.url}, {:name => @folder.name, :url => @folder.url}, {:name => @article.name, :url => @article.url}] | |
54 | + assert_equal links, trail(@block, @article, @profile) | |
55 | + end | |
56 | + | |
57 | + should 'not include profile link on path of links when show_profile is false' do | |
58 | + links = [{:name => @folder.name, :url => @folder.url}, {:name => @article.name, :url => @article.url}] | |
59 | + @block.show_profile = false | |
60 | + assert_equal links, trail(@block, @article, @profile) | |
61 | + end | |
62 | + | |
63 | + should 'not include profile link on path of links when trail is empty' do | |
64 | + assert_equal [], trail(@block, nil, @profile) | |
65 | + end | |
66 | +end | ... | ... |
plugins/breadcrumbs/test/unit/content_breadcrumbs_block_test.rb
... | ... | @@ -6,14 +6,8 @@ class ContentBreadcrumbsBlockTest < ActiveSupport::TestCase |
6 | 6 | |
7 | 7 | def setup |
8 | 8 | @block = BreadcrumbsPlugin::ContentBreadcrumbsBlock.new |
9 | - @profile = fast_create(Community) | |
10 | - @folder = fast_create(Folder, :profile_id => @profile.id) | |
11 | - @article = fast_create(Folder, :profile_id => @profile.id, :parent_id => @folder.id) | |
12 | - @params = {} | |
13 | 9 | end |
14 | 10 | |
15 | - attr_reader :params | |
16 | - | |
17 | 11 | should 'has a description' do |
18 | 12 | assert_not_equal Block.description, BreadcrumbsPlugin::ContentBreadcrumbsBlock.description |
19 | 13 | end |
... | ... | @@ -22,60 +16,28 @@ class ContentBreadcrumbsBlockTest < ActiveSupport::TestCase |
22 | 16 | assert @block.help |
23 | 17 | end |
24 | 18 | |
25 | - should 'return path of links to reach a page' do | |
26 | - links = [{:name => @folder.name, :url => @folder.url}, {:name => @article.name, :url => @article.url}] | |
27 | - assert_equal links, @block.page_trail(@article) | |
28 | - end | |
29 | - | |
30 | - should 'return path of links when current page is at cms controller' do | |
31 | - params = {:controller => 'cms', :action => 'edit', :id => @article.id} | |
32 | - links = [{:name => @folder.name, :url => @folder.url}, {:name => @article.name, :url => @article.url}, {:url=>{:controller=>"cms", :action=>"edit", :id=>@article.id}, :name=>"Edit"}] | |
33 | - assert_equal links, @block.page_trail(nil, params) | |
34 | - end | |
35 | - | |
36 | - should 'not return cms action link when show_cms_action is false' do | |
37 | - params = {:controller => 'cms', :action => 'edit', :id => @article.id} | |
38 | - links = [{:name => @folder.name, :url => @folder.url}, {:name => @article.name, :url => @article.url}] | |
39 | - @block.show_cms_action = false | |
40 | - assert_equal links, @block.page_trail(nil, params) | |
41 | - end | |
42 | - | |
43 | - should 'include profile page link on path of links to reach a profile controller page' do | |
44 | - params = {:controller => 'profile', :action => 'members', :profile => @profile.identifier} | |
45 | - links = [{:name => 'Profile', :url => {:controller => 'profile', :action => 'index', :profile => @profile.identifier}}, {:name => 'Members', :url => {:controller=>'profile', :action=>'members', :profile=> @profile.identifier}}] | |
46 | - assert_equal links, @block.page_trail(nil, params) | |
47 | - end | |
48 | 19 | |
49 | - should 'include only the profile page link on path links when profile action is index' do | |
50 | - params = {:controller => 'profile', :action => 'index', :profile => @profile.identifier} | |
51 | - links = [{:name => 'Profile', :url => {:controller => 'profile', :action => 'index', :profile => @profile.identifier}}] | |
52 | - assert_equal links, @block.page_trail(nil, params) | |
20 | + should 'not be cacheable' do | |
21 | + refute @block.cacheable? | |
53 | 22 | end |
54 | 23 | |
55 | - should 'profile page be the ancestor page of event profile page calendar' do | |
56 | - params = {:controller => 'profile', :action => 'events', :profile => @profile.identifier} | |
57 | - links = [{:name => 'Profile', :url => {:controller => 'profile', :action => 'index', :profile => @profile.identifier}}, {:name => 'Events', :url => {:controller=>'profile', :action=>'events', :profile=> @profile.identifier}}] | |
58 | - assert_equal links, @block.page_trail(nil, params) | |
59 | - end | |
24 | +end | |
60 | 25 | |
61 | - should 'include profile link on path of links to reach a page' do | |
62 | - links = [{:name => @profile.name, :url => @profile.url}, {:name => @folder.name, :url => @folder.url}, {:name => @article.name, :url => @article.url}] | |
63 | - assert_equal links, @block.trail(@article, @profile) | |
64 | - end | |
26 | +require 'boxes_helper' | |
65 | 27 | |
66 | - should 'not include profile link on path of links when show_profile is false' do | |
67 | - links = [{:name => @folder.name, :url => @folder.url}, {:name => @article.name, :url => @article.url}] | |
68 | - @block.show_profile = false | |
69 | - assert_equal links, @block.trail(@article, @profile) | |
70 | - end | |
28 | +class ContentBreadcrumbsBlockViewTest < ActionView::TestCase | |
29 | + include BoxesHelper | |
71 | 30 | |
72 | - should 'not include profile link on path of links when trail is empty' do | |
73 | - assert_equal [], @block.trail(nil, @profile) | |
31 | + def setup | |
32 | + @block = BreadcrumbsPlugin::ContentBreadcrumbsBlock.new | |
33 | + @profile = fast_create(Community) | |
34 | + @folder = fast_create(Folder, :profile_id => @profile.id) | |
35 | + @article = fast_create(Folder, :profile_id => @profile.id, :parent_id => @folder.id) | |
74 | 36 | end |
75 | 37 | |
76 | 38 | should 'render trail if there is links to show' do |
77 | 39 | @page = @article |
78 | - trail = instance_eval(&@block.content) | |
40 | + trail = render_block_content(@block) | |
79 | 41 | assert_match /#{@profile.name}/, trail |
80 | 42 | assert_match /#{@folder.name}/, trail |
81 | 43 | assert_match /#{@page.name}/, trail |
... | ... | @@ -83,11 +45,6 @@ class ContentBreadcrumbsBlockTest < ActiveSupport::TestCase |
83 | 45 | |
84 | 46 | should 'render nothing if there is no links to show' do |
85 | 47 | @page = nil |
86 | - assert_equal '', instance_eval(&@block.content) | |
87 | - end | |
88 | - | |
89 | - should 'not be cacheable' do | |
90 | - refute @block.cacheable? | |
48 | + assert_equal '', render_block_content(@block) | |
91 | 49 | end |
92 | - | |
93 | 50 | end | ... | ... |
... | ... | @@ -0,0 +1 @@ |
1 | +== link_to link[:name], link[:url], :class => 'item' | ... | ... |
plugins/breadcrumbs/views/blocks/content_breadcrumbs.slim
0 → 100644
... | ... | @@ -0,0 +1,11 @@ |
1 | +- extend BreadcrumbsPluginHelper | |
2 | + | |
3 | +- links = trail(block, @page, @profile, params).flatten | |
4 | +- unless links.empty? | |
5 | + == render :partial => 'blocks/link', :collection => links, :as => 'link', :spacer_template => 'blocks/separator' | |
6 | + - if block.show_section_name | |
7 | + div class='section-name' | |
8 | + - if block.show_profile | |
9 | + = links.second[:name] | |
10 | + - else | |
11 | + = links.first[:name] | ... | ... |
plugins/comment_paragraph/lib/comment_paragraph_plugin/api.rb
1 | +# Can't be called Api as will result in: | |
2 | +# warning: toplevel constant Api referenced by CommentParagraphPlugin::Api | |
3 | +# To fix this CommentParagraphPlugin should be a module | |
1 | 4 | class CommentParagraphPlugin::API < Grape::API |
2 | 5 | MAX_PER_PAGE = 20 |
3 | 6 | |
... | ... | @@ -9,7 +12,7 @@ class CommentParagraphPlugin::API < Grape::API |
9 | 12 | comments = comments.without_spam |
10 | 13 | comments = comments.in_paragraph(params[:paragraph_uuid]) |
11 | 14 | comments = comments.without_reply if(params[:without_reply].present?) |
12 | - present paginate(comments), :with => Noosfero::API::Entities::Comment, :current_person => current_person | |
15 | + present paginate(comments), :with => Api::Entities::Comment, :current_person => current_person | |
13 | 16 | end |
14 | 17 | |
15 | 18 | {activate: true, deactivate: false}.each do |method, value| |
... | ... | @@ -19,7 +22,7 @@ class CommentParagraphPlugin::API < Grape::API |
19 | 22 | return forbidden! unless article.comment_paragraph_plugin_enabled? && article.allow_edit?(current_person) |
20 | 23 | article.comment_paragraph_plugin_activate = value |
21 | 24 | article.save! |
22 | - present_partial article, :with => Noosfero::API::Entities::Article | |
25 | + present_partial article, :with => Api::Entities::Article | |
23 | 26 | end |
24 | 27 | end |
25 | 28 | ... | ... |
plugins/comment_paragraph/lib/ext/entities.rb
1 | -require File.join(Rails.root,'lib','noosfero','api','entities') | |
2 | -module Noosfero | |
3 | - module API | |
4 | - module Entities | |
5 | - class Comment < CommentBase | |
6 | - expose :paragraph_uuid | |
7 | - expose :comment_paragraph_selected_area | |
8 | - expose :comment_paragraph_selected_content | |
9 | - end | |
1 | +require_dependency 'api/entities' | |
2 | + | |
3 | +module Api | |
4 | + module Entities | |
5 | + class Comment | |
6 | + expose :paragraph_uuid | |
7 | + expose :comment_paragraph_selected_area | |
8 | + expose :comment_paragraph_selected_content | |
10 | 9 | end |
11 | 10 | end |
12 | 11 | end | ... | ... |