Commit f04df39e5360a895b9e1c15d3ed169901a2e97ef

Authored by Leandro Santos
Committed by Rodrigo Souto
1 parent 8c1e8d15

api: refactoring api to put it at noosfero module

@@ -26,7 +26,7 @@ plugins_tasks.each{ |ext| load ext } @@ -26,7 +26,7 @@ plugins_tasks.each{ |ext| load ext }
26 desc "Print out grape routes" 26 desc "Print out grape routes"
27 task :grape_routes => :environment do 27 task :grape_routes => :environment do
28 #require 'api/api.rb' 28 #require 'api/api.rb'
29 - API::API.routes.each do |route| 29 + Noosfero::API::API.routes.each do |route|
30 puts route 30 puts route
31 method = route.route_method 31 method = route.route_method
32 path = route.route_path 32 path = route.route_path
1 # This file is used by Rack-based servers to start the application. 1 # This file is used by Rack-based servers to start the application.
2 2
3 require ::File.expand_path('../config/environment', __FILE__) 3 require ::File.expand_path('../config/environment', __FILE__)
4 -run Noosfero::Application  
5 -require "config/environment"  
6 -  
7 4
8 #use Rails::Rack::LogTailer 5 #use Rails::Rack::LogTailer
9 #use Rails::Rack::Static 6 #use Rails::Rack::Static
@@ -14,6 +11,6 @@ rails_app = Rack::Builder.new do @@ -14,6 +11,6 @@ rails_app = Rack::Builder.new do
14 end 11 end
15 12
16 run Rack::Cascade.new([ 13 run Rack::Cascade.new([
17 - API::API, 14 + Noosfero::API::API,
18 rails_app 15 rails_app
19 ]) 16 ])
lib/api/api.rb
@@ -1,38 +0,0 @@ @@ -1,38 +0,0 @@
1 -require 'grape'  
2 -Dir["#{Rails.root}/lib/api/*.rb"].each {|file| require file}  
3 -  
4 -module API  
5 - class API < Grape::API  
6 - before { start_log }  
7 - before { setup_multitenancy }  
8 - before { detect_stuff_by_domain }  
9 - after { end_log }  
10 -  
11 - version 'v1'  
12 - prefix "api"  
13 - format :json  
14 - content_type :txt, "text/plain"  
15 -  
16 - helpers APIHelpers  
17 -  
18 - mount V1::Articles  
19 - mount V1::Comments  
20 - mount V1::Users  
21 - mount V1::Communities  
22 - mount V1::People  
23 - mount V1::Enterprises  
24 - mount V1::Categories  
25 - mount Session  
26 -  
27 - # hook point which allow plugins to add Grape::API extensions to API::API  
28 - #finds for plugins which has api mount points classes defined (the class should extends Grape::API)  
29 - @plugins = Noosfero::Plugin.all.map { |p| p.constantize }  
30 - @plugins.each do |klass|  
31 - if klass.public_methods.include? 'api_mount_points'  
32 - klass.api_mount_points.each do |mount_class|  
33 - mount mount_class if mount_class && ( mount_class < Grape::API )  
34 - end  
35 - end  
36 - end  
37 - end  
38 -end  
lib/api/entities.rb
@@ -1,92 +0,0 @@ @@ -1,92 +0,0 @@
1 -module API  
2 - module Entities  
3 -  
4 - Grape::Entity.format_with :timestamp do |date|  
5 - date.strftime('%Y/%m/%d %H:%M:%S') if date  
6 - end  
7 -  
8 - class Image < Grape::Entity  
9 - root 'images', 'image'  
10 -  
11 - expose :icon_url do |image, options|  
12 - image.public_filename(:icon)  
13 - end  
14 -  
15 - expose :minor_url do |image, options|  
16 - image.public_filename(:minor)  
17 - end  
18 -  
19 - expose :portrait_url do |image, options|  
20 - image.public_filename(:portrait)  
21 - end  
22 -  
23 - expose :thumb_url do |image, options|  
24 - image.public_filename(:thumb)  
25 - end  
26 - end  
27 -  
28 - class Profile < Grape::Entity  
29 - expose :identifier, :name, :id  
30 - expose :created_at, :format_with => :timestamp  
31 - expose :image, :using => Image  
32 - end  
33 -  
34 - class Person < Profile  
35 - root 'people', 'person'  
36 - end  
37 - class Enterprise < Profile  
38 - root 'enterprises', 'enterprise'  
39 - end  
40 - class Community < Profile  
41 - root 'communities', 'community'  
42 - expose :description  
43 - end  
44 -  
45 - class Category < Grape::Entity  
46 - root 'categories', 'category'  
47 - expose :name, :id, :slug  
48 - expose :image, :using => Image  
49 - end  
50 -  
51 -  
52 - class Article < Grape::Entity  
53 - root 'articles', 'article'  
54 - expose :id, :body  
55 - expose :created_at, :format_with => :timestamp  
56 - expose :title, :documentation => {:type => "String", :desc => "Title of the article"}  
57 - expose :created_by, :as => :author, :using => Profile  
58 - expose :profile, :using => Profile  
59 - expose :categories, :using => Category  
60 - expose :parent, :using => Article  
61 - end  
62 -  
63 - class Comment < Grape::Entity  
64 - root 'comments', 'comment'  
65 - expose :body, :title, :id  
66 - expose :created_at, :format_with => :timestamp  
67 - expose :author, :using => Profile  
68 - end  
69 -  
70 -  
71 - class User < Grape::Entity  
72 - root 'users', 'user'  
73 - expose :id  
74 - expose :login  
75 - expose :person, :using => Profile  
76 - expose :permissions do |user, options|  
77 - output = {}  
78 - user.person.role_assignments.map do |role_assigment|  
79 - if role_assigment.resource.respond_to?(:identifier)  
80 - output[role_assigment.resource.identifier] = role_assigment.role.permissions  
81 - end  
82 - end  
83 - output  
84 - end  
85 - end  
86 -  
87 - class UserLogin < User  
88 - expose :private_token  
89 - end  
90 -  
91 - end  
92 -end  
lib/api/helpers.rb
@@ -1,187 +0,0 @@ @@ -1,187 +0,0 @@
1 -module API  
2 - module APIHelpers  
3 - PRIVATE_TOKEN_PARAM = :private_token  
4 -  
5 - def logger  
6 - @logger ||= Logger.new(File.join(Rails.root, 'log', "#{ENV['RAILS_ENV']}_api.log"))  
7 - end  
8 -  
9 - def current_user  
10 - private_token = params[PRIVATE_TOKEN_PARAM].to_s if params  
11 - @current_user ||= User.find_by_private_token(private_token)  
12 - @current_user = nil if !@current_user.nil? && @current_user.private_token_expired?  
13 - @current_user  
14 - end  
15 -  
16 - def current_person  
17 - current_user.person unless current_user.nil?  
18 - end  
19 -  
20 - def logout  
21 - @current_user = nil  
22 - end  
23 -  
24 - def environment  
25 - @environment  
26 - end  
27 -  
28 - def limit  
29 - limit = params[:limit].to_i  
30 - limit = default_limit if limit <= 0  
31 - limit  
32 - end  
33 -  
34 - def period(from_date, until_date)  
35 - return nil if from_date.nil? && until_date.nil?  
36 -  
37 - begin_period = from_date.nil? ? Time.at(0).to_datetime : from_date  
38 - end_period = until_date.nil? ? DateTime.now : until_date  
39 -  
40 - begin_period..end_period  
41 - end  
42 -  
43 - def parse_content_type(content_type)  
44 - return nil if content_type.blank?  
45 - content_type.split(',').map do |content_type|  
46 - content_type.camelcase  
47 - end  
48 - end  
49 -  
50 - def find_article(articles, id)  
51 - article = articles.find(id)  
52 - article.display_to?(current_user.person) ? article : forbidden!  
53 - end  
54 -  
55 - def make_conditions_with_parameter(params = {})  
56 - conditions = {}  
57 - from_date = DateTime.parse(params[:from]) if params[:from]  
58 - until_date = DateTime.parse(params[:until]) if params[:until]  
59 -  
60 - conditions[:type] = parse_content_type(params[:content_type]) unless params[:content_type].nil?  
61 -  
62 - conditions[:created_at] = period(from_date, until_date) if from_date || until_date  
63 -  
64 - conditions  
65 - end  
66 -  
67 -  
68 - def select_filtered_collection_of(object, method, params)  
69 - conditions = make_conditions_with_parameter(params)  
70 -  
71 - if params[:reference_id]  
72 - objects = object.send(method).send("#{params.key?(:oldest) ? 'older_than' : 'newer_than'}", params[:reference_id]).where(conditions).limit(limit).order("created_at DESC")  
73 - else  
74 - objects = object.send(method).where(conditions).limit(limit).order("created_at DESC")  
75 - end  
76 - objects  
77 - end  
78 -  
79 - def authenticate!  
80 - unauthorized! unless current_user  
81 - end  
82 -  
83 - # Checks the occurrences of uniqueness of attributes, each attribute must be present in the params hash  
84 - # or a Bad Request error is invoked.  
85 - #  
86 - # Parameters:  
87 - # keys (unique) - A hash consisting of keys that must be unique  
88 - def unique_attributes!(obj, keys)  
89 - keys.each do |key|  
90 - cant_be_saved_request!(key) if obj.send("find_by_#{key.to_s}", params[key])  
91 - end  
92 - end  
93 -  
94 - def attributes_for_keys(keys)  
95 - attrs = {}  
96 - keys.each do |key|  
97 - attrs[key] = params[key] if params[key].present? or (params.has_key?(key) and params[key] == false)  
98 - end  
99 - attrs  
100 - end  
101 -  
102 - ##########################################  
103 - # error helpers #  
104 - ##########################################  
105 -  
106 - def forbidden!  
107 - render_api_error!('403 Forbidden', 403)  
108 - end  
109 -  
110 - def cant_be_saved_request!(attribute)  
111 - message = _("(Invalid request) #{attribute} can't be saved")  
112 - render_api_error!(message, 400)  
113 - end  
114 -  
115 - def bad_request!(attribute)  
116 - message = _("(Bad request) #{attribute} not given")  
117 - render_api_error!(message, 400)  
118 - end  
119 -  
120 - def something_wrong!  
121 - message = _("Something wrong happened")  
122 - render_api_error!(message, 400)  
123 - end  
124 -  
125 - def unauthorized!  
126 - render_api_error!(_('Unauthorized'), 401)  
127 - end  
128 -  
129 - def not_allowed!  
130 - render_api_error!(_('Method Not Allowed'), 405)  
131 - end  
132 -  
133 - def render_api_error!(message, status)  
134 - error!({'message' => message, :code => status}, status)  
135 - end  
136 -  
137 - def render_api_errors!(messages)  
138 - render_api_error!(messages.join(','), 400)  
139 - end  
140 - protected  
141 -  
142 - def start_log  
143 - logger.info "Started #{request.path} #{request.params.except('password')}"  
144 - end  
145 - def end_log  
146 - logger.info "Completed #{request.path}"  
147 - end  
148 -  
149 - def setup_multitenancy  
150 - Noosfero::MultiTenancy.setup!(request.host)  
151 - end  
152 -  
153 - def detect_stuff_by_domain  
154 - @domain = Domain.find_by_name(request.host)  
155 - if @domain.nil?  
156 - @environment = Environment.default  
157 - if @environment.nil? && Rails.env.development?  
158 - # This should only happen in development ...  
159 - @environment = Environment.create!(:name => "Noosfero", :is_default => true)  
160 - end  
161 - else  
162 - @environment = @domain.environment  
163 - end  
164 - end  
165 -  
166 - private  
167 -  
168 - def default_limit  
169 - 20  
170 - end  
171 -  
172 - def parse_content_type(content_type)  
173 - return nil if content_type.blank?  
174 - content_type.split(',').map do |content_type|  
175 - content_type.camelcase  
176 - end  
177 - end  
178 -  
179 - def period(from_date, until_date)  
180 - begin_period = from_date.nil? ? Time.at(0).to_datetime : from_date  
181 - end_period = until_date.nil? ? DateTime.now : until_date  
182 -  
183 - begin_period..end_period  
184 - end  
185 -  
186 - end  
187 -end  
lib/api/session.rb
@@ -1,48 +0,0 @@ @@ -1,48 +0,0 @@
1 -module API  
2 -  
3 - class Session < Grape::API  
4 -  
5 - # Login to get token  
6 - #  
7 - # Parameters:  
8 - # login (*required) - user login or email  
9 - # password (required) - user password  
10 - #  
11 - # Example Request:  
12 - # POST http://localhost:3000/api/v1/login?login=adminuser&password=admin  
13 - post "/login" do  
14 - user ||= User.authenticate(params[:login], params[:password], environment)  
15 -  
16 - return unauthorized! unless user  
17 - user.generate_private_token!  
18 - present user, :with => Entities::UserLogin  
19 - end  
20 -  
21 - # Create user.  
22 - #  
23 - # Parameters:  
24 - # email (required) - Email  
25 - # password (required) - Password  
26 - # login - login  
27 - # Example Request:  
28 - # POST /register?email=some@mail.com&password=pas&login=some  
29 - params do  
30 - requires :email, type: String, desc: _("Email")  
31 - requires :login, type: String, desc: _("Login")  
32 - requires :password, type: String, desc: _("Password")  
33 - end  
34 - post "/register" do  
35 - unique_attributes! User, [:email, :login]  
36 - attrs = attributes_for_keys [:email, :login, :password]  
37 - attrs[:password_confirmation] = attrs[:password]  
38 - user = User.new(attrs)  
39 - if user.save  
40 - user.activate  
41 - present user, :with => Entities::User  
42 - else  
43 - something_wrong!  
44 - end  
45 - end  
46 -  
47 - end  
48 -end  
lib/api/v1/articles.rb
@@ -1,167 +0,0 @@ @@ -1,167 +0,0 @@
1 -module API  
2 - module V1  
3 - class Articles < Grape::API  
4 - before { authenticate! }  
5 -  
6 - ARTICLE_TYPES = Article.descendants.map{|a| a.to_s}  
7 -  
8 - resource :articles do  
9 -  
10 - # Collect articles  
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/articles?from=2013-04-04-14:41:43&until=2015-04-04-14:41:43&limit=10&private_token=e96fff37c2238fdab074d1dcea8e6317  
19 - get do  
20 - articles = select_filtered_collection_of(environment, 'articles', params)  
21 - articles = articles.display_filter(current_person, nil)  
22 - present articles, :with => Entities::Article  
23 - end  
24 -  
25 - desc "Return the article id"  
26 - get ':id' do  
27 - article = find_article(environment.articles, params[:id])  
28 - present article, :with => Entities::Article  
29 - end  
30 -  
31 - get ':id/children' do  
32 - article = find_article(environment.articles, params[:id])  
33 - articles = select_filtered_collection_of(article, 'children', params)  
34 - articles = articles.display_filter(current_person, nil)  
35 - present articles, :with => Entities::Article  
36 - end  
37 -  
38 - get ':id/children/:child_id' do  
39 - article = find_article(environment.articles, params[:id])  
40 - present find_article(article.children, params[:child_id]), :with => Entities::Article  
41 - end  
42 -  
43 - end  
44 -  
45 - resource :communities do  
46 - segment '/:community_id' do  
47 - resource :articles do  
48 - get do  
49 - community = environment.communities.find(params[:community_id])  
50 - articles = select_filtered_collection_of(community, 'articles', params)  
51 - articles = articles.display_filter(current_person, community)  
52 - present articles, :with => Entities::Article  
53 - end  
54 -  
55 - get ':id' do  
56 - community = environment.communities.find(params[:community_id])  
57 - article = find_article(community.articles, params[:id])  
58 - present article, :with => Entities::Article  
59 - end  
60 -  
61 - # Example Request:  
62 - # POST api/v1/communites/:community_id/articles?private_token=234298743290432&article[name]=title&article[body]=body  
63 - post do  
64 - community = environment.communities.find(params[:community_id])  
65 - return forbidden! unless current_person.can_post_content?(community)  
66 -  
67 - klass_type= params[:content_type].nil? ? 'TinyMceArticle' : params[:content_type]  
68 - return forbidden! unless ARTICLE_TYPES.include?(klass_type)  
69 -  
70 - article = klass_type.constantize.new(params[:article])  
71 - article.last_changed_by = current_person  
72 - article.created_by= current_person  
73 - article.profile = community  
74 -  
75 - if !article.save  
76 - render_api_errors!(article.errors.full_messages)  
77 - end  
78 - present article, :with => Entities::Article  
79 - end  
80 -  
81 - end  
82 - end  
83 -  
84 - end  
85 -  
86 - resource :people do  
87 - segment '/:person_id' do  
88 - resource :articles do  
89 - get do  
90 - person = environment.people.find(params[:person_id])  
91 - articles = select_filtered_collection_of(person, 'articles', params)  
92 - articles = articles.display_filter(current_person, person)  
93 - present articles, :with => Entities::Article  
94 - end  
95 -  
96 - get ':id' do  
97 - person = environment.people.find(params[:person_id])  
98 - article = find_article(person.articles, params[:id])  
99 - present article, :with => Entities::Article  
100 - end  
101 -  
102 - post do  
103 - person = environment.people.find(params[:person_id])  
104 - return forbidden! unless current_person.can_post_content?(person)  
105 -  
106 - klass_type= params[:content_type].nil? ? 'TinyMceArticle' : params[:content_type]  
107 - return forbidden! unless ARTICLE_TYPES.include?(klass_type)  
108 -  
109 - article = klass_type.constantize.new(params[:article])  
110 - article.last_changed_by = current_person  
111 - article.created_by= current_person  
112 - article.profile = person  
113 -  
114 - if !article.save  
115 - render_api_errors!(article.errors.full_messages)  
116 - end  
117 - present article, :with => Entities::Article  
118 - end  
119 -  
120 - end  
121 - end  
122 -  
123 - end  
124 -  
125 - resource :enterprises do  
126 - segment '/:enterprise_id' do  
127 - resource :articles do  
128 - get do  
129 - enterprise = environment.enterprises.find(params[:enterprise_id])  
130 - articles = select_filtered_collection_of(enterprise, 'articles', params)  
131 - articles = articles.display_filter(current_person, enterprise)  
132 - present articles, :with => Entities::Article  
133 - end  
134 -  
135 - get ':id' do  
136 - enterprise = environment.enterprises.find(params[:enterprise_id])  
137 - article = find_article(enterprise.articles, params[:id])  
138 - present article, :with => Entities::Article  
139 - end  
140 -  
141 - post do  
142 - enterprise = environment.enterprises.find(params[:enterprise_id])  
143 - return forbidden! unless current_person.can_post_content?(enterprise)  
144 -  
145 - klass_type= params[:content_type].nil? ? 'TinyMceArticle' : params[:content_type]  
146 - return forbidden! unless ARTICLE_TYPES.include?(klass_type)  
147 -  
148 - article = klass_type.constantize.new(params[:article])  
149 - article.last_changed_by = current_person  
150 - article.created_by= current_person  
151 - article.profile = enterprise  
152 -  
153 - if !article.save  
154 - render_api_errors!(article.errors.full_messages)  
155 - end  
156 - present article, :with => Entities::Article  
157 - end  
158 -  
159 - end  
160 - end  
161 -  
162 - end  
163 -  
164 -  
165 - end  
166 - end  
167 -end  
lib/api/v1/categories.rb
@@ -1,23 +0,0 @@ @@ -1,23 +0,0 @@
1 -module API  
2 - module V1  
3 - class Categories < Grape::API  
4 - before { authenticate! }  
5 -  
6 - resource :categories do  
7 -  
8 - get do  
9 - type = params[:category_type]  
10 - categories = type.nil? ? environment.categories : environment.categories.find(:all, :conditions => {:type => type})  
11 - present categories, :with => Entities::Category  
12 - end  
13 -  
14 - desc "Return the category by id"  
15 - get ':id' do  
16 - present environment.categories.find(params[:id]), :with => Entities::Category  
17 - end  
18 -  
19 - end  
20 -  
21 - end  
22 - end  
23 -end  
lib/api/v1/comments.rb
@@ -1,45 +0,0 @@ @@ -1,45 +0,0 @@
1 -module API  
2 - module V1  
3 - class Comments < Grape::API  
4 - before { authenticate! }  
5 -  
6 - resource :articles do  
7 - # Collect comments from articles  
8 - #  
9 - # Parameters:  
10 - # reference_id - comment id used as reference to collect comment  
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 /articles/12/comments?oldest&limit=10&reference_id=23  
16 - get ":id/comments" do  
17 -  
18 - conditions = make_conditions_with_parameter(params)  
19 - article = find_article(environment.articles, params[:id])  
20 -  
21 - if params[:reference_id]  
22 - comments = article.comments.send("#{params.key?(:oldest) ? 'older_than' : 'newer_than'}", params[:reference_id]).reorder("created_at DESC").find(:all, :conditions => conditions, :limit => limit)  
23 - else  
24 - comments = article.comments.reorder("created_at DESC").find(:all, :conditions => conditions, :limit => limit)  
25 - end  
26 - present comments, :with => Entities::Comment  
27 -  
28 - end  
29 -  
30 - get ":id/comments/:comment_id" do  
31 - article = find_article(environment.articles, params[:id])  
32 - present article.comments.find(params[:comment_id]), :with => Entities::Comment  
33 - end  
34 -  
35 - # Example Request:  
36 - # POST api/v1/articles/12/comments?private_toke=234298743290432&body=new comment  
37 - post ":id/comments" do  
38 - article = find_article(environment.articles, params[:id])  
39 - present article.comments.create(:author => current_person, :body => params[:body]), :with => Entities::Comment  
40 - end  
41 - end  
42 -  
43 - end  
44 - end  
45 -end  
lib/api/v1/communities.rb
@@ -1,70 +0,0 @@ @@ -1,70 +0,0 @@
1 -module API  
2 - module V1  
3 - class Communities < Grape::API  
4 - before { authenticate! }  
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 = communities.visible_for_person(current_person)  
21 - present communities, :with => Entities::Community  
22 - end  
23 -  
24 -  
25 - # Example Request:  
26 - # POST api/v1/communties?private_token=234298743290432&community[name]=some_name  
27 - post do  
28 - params[:community] ||= {}  
29 - begin  
30 - community = Community.create_after_moderation(current_person, params[:community].merge({:environment => environment}))  
31 - rescue  
32 - community = Community.new(params[:community])  
33 - end  
34 -  
35 - if !community.save  
36 - render_api_errors!(community.errors.full_messages)  
37 - end  
38 -  
39 - present community, :with => Entities::Community  
40 - end  
41 -  
42 - get ':id' do  
43 - community = environment.communities.visible.find_by_id(params[:id])  
44 - present community, :with => Entities::Community  
45 - end  
46 -  
47 - end  
48 -  
49 - resource :people do  
50 -  
51 - segment '/:person_id' do  
52 -  
53 - resource :communities do  
54 -  
55 - get do  
56 - person = environment.people.find(params[:person_id])  
57 - communities = select_filtered_collection_of(person, 'communities', params)  
58 - communities = communities.visible  
59 - present communities, :with => Entities::Community  
60 - end  
61 -  
62 - end  
63 -  
64 - end  
65 -  
66 - end  
67 -  
68 - end  
69 - end  
70 -end  
lib/api/v1/enterprises.rb
@@ -1,54 +0,0 @@ @@ -1,54 +0,0 @@
1 -module API  
2 - module V1  
3 - class Enterprises < Grape::API  
4 - before { authenticate! }  
5 -  
6 - resource :enterprises 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 /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_for_person(current_person)  
21 - present enterprises, :with => Entities::Enterprise  
22 - end  
23 -  
24 - desc "Return one enterprise by id"  
25 - get ':id' do  
26 - enterprise = environment.enterprises.visible.find_by_id(params[:id])  
27 - present enterprise, :with => Entities::Enterprise  
28 - end  
29 -  
30 - end  
31 -  
32 - resource :people do  
33 -  
34 - segment '/:person_id' do  
35 -  
36 - resource :enterprises do  
37 -  
38 - get do  
39 - person = environment.people.find(params[:person_id])  
40 - enterprises = select_filtered_collection_of(person, 'enterprises', params)  
41 - enterprises = enterprises.visible  
42 - present enterprises, :with => Entities::Enterprise  
43 - end  
44 -  
45 - end  
46 -  
47 - end  
48 -  
49 - end  
50 -  
51 -  
52 - end  
53 - end  
54 -end  
lib/api/v1/people.rb
@@ -1,40 +0,0 @@ @@ -1,40 +0,0 @@
1 -module API  
2 - module V1  
3 - class People < Grape::API  
4 - before { authenticate! }  
5 -  
6 - resource :people 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 /people?from=2013-04-04-14:41:43&until=2014-04-04-14:41:43&limit=10  
17 - # GET /people?reference_id=10&limit=10&oldest  
18 - get do  
19 - people = select_filtered_collection_of(environment, 'people', params)  
20 - people = people.visible_for_person(current_person)  
21 - present people, :with => Entities::Person  
22 - end  
23 -  
24 - desc "Return the person information"  
25 - get ':id' do  
26 - person = environment.people.visible.find_by_id(params[:id])  
27 - present person, :with => Entities::Person  
28 - end  
29 -  
30 - desc "Return the person friends"  
31 - get ':id/friends' do  
32 - friends = current_person.friends.visible  
33 - present friends, :with => Entities::Person  
34 - end  
35 -  
36 - end  
37 -  
38 - end  
39 - end  
40 -end  
lib/api/v1/users.rb
@@ -1,46 +0,0 @@ @@ -1,46 +0,0 @@
1 -module API  
2 - module V1  
3 - class Users < Grape::API  
4 - before { authenticate! }  
5 -  
6 - resource :users do  
7 -  
8 - #FIXME make the pagination  
9 - #FIXME put it on environment context  
10 - get do  
11 - present environment.users, :with => Entities::User  
12 - end  
13 -  
14 - # Example Request:  
15 - # POST api/v1/users?user[login]=some_login&user[password]=some  
16 - post do  
17 - user = User.new(params[:user])  
18 - user.terms_of_use = environment.terms_of_use  
19 - user.environment = environment  
20 - if !user.save  
21 - render_api_errors!(user.errors.full_messages)  
22 - end  
23 -  
24 - present user, :with => Entities::User  
25 - end  
26 -  
27 - get ":id" do  
28 - present environment.users.find_by_id(params[:id]), :with => Entities::User  
29 - end  
30 -  
31 - get ":id/permissions" do  
32 - user = environment.users.find(params[:id])  
33 - output = {}  
34 - user.person.role_assignments.map do |role_assigment|  
35 - if role_assigment.resource.respond_to?(:identifier) && role_assigment.resource.identifier == params[:profile]  
36 - output[:permissions] = role_assigment.role.permissions  
37 - end  
38 - end  
39 - present output  
40 - end  
41 -  
42 - end  
43 -  
44 - end  
45 - end  
46 -end  
lib/noosfero/api/api.rb 0 → 100644
@@ -0,0 +1,39 @@ @@ -0,0 +1,39 @@
  1 +require 'grape'
  2 +Dir["#{Rails.root}/lib/noosfero/api/*.rb"].each {|file| require file}
  3 +module Noosfero
  4 + module API
  5 + class API < Grape::API
  6 + before { start_log }
  7 + before { setup_multitenancy }
  8 + before { detect_stuff_by_domain }
  9 + after { end_log }
  10 +
  11 + version 'v1'
  12 + prefix "api"
  13 + format :json
  14 + content_type :txt, "text/plain"
  15 +
  16 + helpers APIHelpers
  17 +
  18 + mount V1::Articles
  19 + mount V1::Comments
  20 + mount V1::Users
  21 + mount V1::Communities
  22 + mount V1::People
  23 + mount V1::Enterprises
  24 + mount V1::Categories
  25 + mount Session
  26 +
  27 + # hook point which allow plugins to add Grape::API extensions to API::API
  28 + #finds for plugins which has api mount points classes defined (the class should extends Grape::API)
  29 + @plugins = Noosfero::Plugin.all.map { |p| p.constantize }
  30 + @plugins.each do |klass|
  31 + if klass.public_methods.include? 'api_mount_points'
  32 + klass.api_mount_points.each do |mount_class|
  33 + mount mount_class if mount_class && ( mount_class < Grape::API )
  34 + end
  35 + end
  36 + end
  37 + end
  38 + end
  39 +end
lib/noosfero/api/entities.rb 0 → 100644
@@ -0,0 +1,94 @@ @@ -0,0 +1,94 @@
  1 +module Noosfero
  2 + module API
  3 + module Entities
  4 +
  5 + Grape::Entity.format_with :timestamp do |date|
  6 + date.strftime('%Y/%m/%d %H:%M:%S') if date
  7 + end
  8 +
  9 + class Image < Grape::Entity
  10 + root 'images', 'image'
  11 +
  12 + expose :icon_url do |image, options|
  13 + image.public_filename(:icon)
  14 + end
  15 +
  16 + expose :minor_url do |image, options|
  17 + image.public_filename(:minor)
  18 + end
  19 +
  20 + expose :portrait_url do |image, options|
  21 + image.public_filename(:portrait)
  22 + end
  23 +
  24 + expose :thumb_url do |image, options|
  25 + image.public_filename(:thumb)
  26 + end
  27 + end
  28 +
  29 + class Profile < Grape::Entity
  30 + expose :identifier, :name, :id
  31 + expose :created_at, :format_with => :timestamp
  32 + expose :image, :using => Image
  33 + end
  34 +
  35 + class Person < Profile
  36 + root 'people', 'person'
  37 + end
  38 + class Enterprise < Profile
  39 + root 'enterprises', 'enterprise'
  40 + end
  41 + class Community < Profile
  42 + root 'communities', 'community'
  43 + expose :description
  44 + end
  45 +
  46 + class Category < Grape::Entity
  47 + root 'categories', 'category'
  48 + expose :name, :id, :slug
  49 + expose :image, :using => Image
  50 + end
  51 +
  52 +
  53 + class Article < Grape::Entity
  54 + root 'articles', 'article'
  55 + expose :id, :body
  56 + expose :created_at, :format_with => :timestamp
  57 + expose :title, :documentation => {:type => "String", :desc => "Title of the article"}
  58 + expose :created_by, :as => :author, :using => Profile
  59 + expose :profile, :using => Profile
  60 + expose :categories, :using => Category
  61 + expose :parent, :using => Article
  62 + end
  63 +
  64 + class Comment < Grape::Entity
  65 + root 'comments', 'comment'
  66 + expose :body, :title, :id
  67 + expose :created_at, :format_with => :timestamp
  68 + expose :author, :using => Profile
  69 + end
  70 +
  71 +
  72 + class User < Grape::Entity
  73 + root 'users', 'user'
  74 + expose :id
  75 + expose :login
  76 + expose :person, :using => Profile
  77 + expose :permissions do |user, options|
  78 + output = {}
  79 + user.person.role_assignments.map do |role_assigment|
  80 + if role_assigment.resource.respond_to?(:identifier)
  81 + output[role_assigment.resource.identifier] = role_assigment.role.permissions
  82 + end
  83 + end
  84 + output
  85 + end
  86 + end
  87 +
  88 + class UserLogin < User
  89 + expose :private_token
  90 + end
  91 +
  92 + end
  93 + end
  94 +end
lib/noosfero/api/helpers.rb 0 → 100644
@@ -0,0 +1,189 @@ @@ -0,0 +1,189 @@
  1 +module Noosfero
  2 + module API
  3 + module APIHelpers
  4 + PRIVATE_TOKEN_PARAM = :private_token
  5 +
  6 + def logger
  7 + @logger ||= Logger.new(File.join(Rails.root, 'log', "#{ENV['RAILS_ENV']}_api.log"))
  8 + end
  9 +
  10 + def current_user
  11 + private_token = params[PRIVATE_TOKEN_PARAM].to_s if params
  12 + @current_user ||= User.find_by_private_token(private_token)
  13 + @current_user = nil if !@current_user.nil? && @current_user.private_token_expired?
  14 + @current_user
  15 + end
  16 +
  17 + def current_person
  18 + current_user.person unless current_user.nil?
  19 + end
  20 +
  21 + def logout
  22 + @current_user = nil
  23 + end
  24 +
  25 + def environment
  26 + @environment
  27 + end
  28 +
  29 + def limit
  30 + limit = params[:limit].to_i
  31 + limit = default_limit if limit <= 0
  32 + limit
  33 + end
  34 +
  35 + def period(from_date, until_date)
  36 + return nil if from_date.nil? && until_date.nil?
  37 +
  38 + begin_period = from_date.nil? ? Time.at(0).to_datetime : from_date
  39 + end_period = until_date.nil? ? DateTime.now : until_date
  40 +
  41 + begin_period..end_period
  42 + end
  43 +
  44 + def parse_content_type(content_type)
  45 + return nil if content_type.blank?
  46 + content_type.split(',').map do |content_type|
  47 + content_type.camelcase
  48 + end
  49 + end
  50 +
  51 + def find_article(articles, id)
  52 + article = articles.find(id)
  53 + article.display_to?(current_user.person) ? article : forbidden!
  54 + end
  55 +
  56 + def make_conditions_with_parameter(params = {})
  57 + conditions = {}
  58 + from_date = DateTime.parse(params[:from]) if params[:from]
  59 + until_date = DateTime.parse(params[:until]) if params[:until]
  60 +
  61 + conditions[:type] = parse_content_type(params[:content_type]) unless params[:content_type].nil?
  62 +
  63 + conditions[:created_at] = period(from_date, until_date) if from_date || until_date
  64 +
  65 + conditions
  66 + end
  67 +
  68 +
  69 + def select_filtered_collection_of(object, method, params)
  70 + conditions = make_conditions_with_parameter(params)
  71 +
  72 + if params[:reference_id]
  73 + objects = object.send(method).send("#{params.key?(:oldest) ? 'older_than' : 'newer_than'}", params[:reference_id]).where(conditions).limit(limit).order("created_at DESC")
  74 + else
  75 + objects = object.send(method).where(conditions).limit(limit).order("created_at DESC")
  76 + end
  77 + objects
  78 + end
  79 +
  80 + def authenticate!
  81 + unauthorized! unless current_user
  82 + end
  83 +
  84 + # Checks the occurrences of uniqueness of attributes, each attribute must be present in the params hash
  85 + # or a Bad Request error is invoked.
  86 + #
  87 + # Parameters:
  88 + # keys (unique) - A hash consisting of keys that must be unique
  89 + def unique_attributes!(obj, keys)
  90 + keys.each do |key|
  91 + cant_be_saved_request!(key) if obj.send("find_by_#{key.to_s}", params[key])
  92 + end
  93 + end
  94 +
  95 + def attributes_for_keys(keys)
  96 + attrs = {}
  97 + keys.each do |key|
  98 + attrs[key] = params[key] if params[key].present? or (params.has_key?(key) and params[key] == false)
  99 + end
  100 + attrs
  101 + end
  102 +
  103 + ##########################################
  104 + # error helpers #
  105 + ##########################################
  106 +
  107 + def forbidden!
  108 + render_api_error!('403 Forbidden', 403)
  109 + end
  110 +
  111 + def cant_be_saved_request!(attribute)
  112 + message = _("(Invalid request) #{attribute} can't be saved")
  113 + render_api_error!(message, 400)
  114 + end
  115 +
  116 + def bad_request!(attribute)
  117 + message = _("(Bad request) #{attribute} not given")
  118 + render_api_error!(message, 400)
  119 + end
  120 +
  121 + def something_wrong!
  122 + message = _("Something wrong happened")
  123 + render_api_error!(message, 400)
  124 + end
  125 +
  126 + def unauthorized!
  127 + render_api_error!(_('Unauthorized'), 401)
  128 + end
  129 +
  130 + def not_allowed!
  131 + render_api_error!(_('Method Not Allowed'), 405)
  132 + end
  133 +
  134 + def render_api_error!(message, status)
  135 + error!({'message' => message, :code => status}, status)
  136 + end
  137 +
  138 + def render_api_errors!(messages)
  139 + render_api_error!(messages.join(','), 400)
  140 + end
  141 + protected
  142 +
  143 + def start_log
  144 + logger.info "Started #{request.path} #{request.params.except('password')}"
  145 + end
  146 + def end_log
  147 + logger.info "Completed #{request.path}"
  148 + end
  149 +
  150 + def setup_multitenancy
  151 + Noosfero::MultiTenancy.setup!(request.host)
  152 + end
  153 +
  154 + def detect_stuff_by_domain
  155 + @domain = Domain.find_by_name(request.host)
  156 + if @domain.nil?
  157 + @environment = Environment.default
  158 + if @environment.nil? && Rails.env.development?
  159 + # This should only happen in development ...
  160 + @environment = Environment.create!(:name => "Noosfero", :is_default => true)
  161 + end
  162 + else
  163 + @environment = @domain.environment
  164 + end
  165 + end
  166 +
  167 + private
  168 +
  169 + def default_limit
  170 + 20
  171 + end
  172 +
  173 + def parse_content_type(content_type)
  174 + return nil if content_type.blank?
  175 + content_type.split(',').map do |content_type|
  176 + content_type.camelcase
  177 + end
  178 + end
  179 +
  180 + def period(from_date, until_date)
  181 + begin_period = from_date.nil? ? Time.at(0).to_datetime : from_date
  182 + end_period = until_date.nil? ? DateTime.now : until_date
  183 +
  184 + begin_period..end_period
  185 + end
  186 +
  187 + end
  188 + end
  189 +end
lib/noosfero/api/session.rb 0 → 100644
@@ -0,0 +1,50 @@ @@ -0,0 +1,50 @@
  1 +module Noosfero
  2 + module API
  3 +
  4 + class Session < Grape::API
  5 +
  6 + # Login to get token
  7 + #
  8 + # Parameters:
  9 + # login (*required) - user login or email
  10 + # password (required) - user password
  11 + #
  12 + # Example Request:
  13 + # POST http://localhost:3000/api/v1/login?login=adminuser&password=admin
  14 + post "/login" do
  15 + user ||= User.authenticate(params[:login], params[:password], environment)
  16 +
  17 + return unauthorized! unless user
  18 + user.generate_private_token!
  19 + present user, :with => Entities::UserLogin
  20 + end
  21 +
  22 + # Create user.
  23 + #
  24 + # Parameters:
  25 + # email (required) - Email
  26 + # password (required) - Password
  27 + # login - login
  28 + # Example Request:
  29 + # POST /register?email=some@mail.com&password=pas&login=some
  30 + params do
  31 + requires :email, type: String, desc: _("Email")
  32 + requires :login, type: String, desc: _("Login")
  33 + requires :password, type: String, desc: _("Password")
  34 + end
  35 + post "/register" do
  36 + unique_attributes! User, [:email, :login]
  37 + attrs = attributes_for_keys [:email, :login, :password]
  38 + attrs[:password_confirmation] = attrs[:password]
  39 + user = User.new(attrs)
  40 + if user.save
  41 + user.activate
  42 + present user, :with => Entities::User
  43 + else
  44 + something_wrong!
  45 + end
  46 + end
  47 +
  48 + end
  49 + end
  50 +end
lib/noosfero/api/v1/articles.rb 0 → 100644
@@ -0,0 +1,169 @@ @@ -0,0 +1,169 @@
  1 +module Noosfero
  2 + module API
  3 + module V1
  4 + class Articles < Grape::API
  5 + before { authenticate! }
  6 +
  7 + ARTICLE_TYPES = Article.descendants.map{|a| a.to_s}
  8 +
  9 + resource :articles do
  10 +
  11 + # Collect articles
  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/articles?from=2013-04-04-14:41:43&until=2015-04-04-14:41:43&limit=10&private_token=e96fff37c2238fdab074d1dcea8e6317
  20 + get do
  21 + articles = select_filtered_collection_of(environment, 'articles', params)
  22 + articles = articles.display_filter(current_person, nil)
  23 + present articles, :with => Entities::Article
  24 + end
  25 +
  26 + desc "Return the article id"
  27 + get ':id' do
  28 + article = find_article(environment.articles, params[:id])
  29 + present article, :with => Entities::Article
  30 + end
  31 +
  32 + get ':id/children' do
  33 + article = find_article(environment.articles, params[:id])
  34 + articles = select_filtered_collection_of(article, 'children', params)
  35 + articles = articles.display_filter(current_person, nil)
  36 + present articles, :with => Entities::Article
  37 + end
  38 +
  39 + get ':id/children/:child_id' do
  40 + article = find_article(environment.articles, params[:id])
  41 + present find_article(article.children, params[:child_id]), :with => Entities::Article
  42 + end
  43 +
  44 + end
  45 +
  46 + resource :communities do
  47 + segment '/:community_id' do
  48 + resource :articles do
  49 + get do
  50 + community = environment.communities.find(params[:community_id])
  51 + articles = select_filtered_collection_of(community, 'articles', params)
  52 + articles = articles.display_filter(current_person, community)
  53 + present articles, :with => Entities::Article
  54 + end
  55 +
  56 + get ':id' do
  57 + community = environment.communities.find(params[:community_id])
  58 + article = find_article(community.articles, params[:id])
  59 + present article, :with => Entities::Article
  60 + end
  61 +
  62 + # Example Request:
  63 + # POST api/v1/communites/:community_id/articles?private_token=234298743290432&article[name]=title&article[body]=body
  64 + post do
  65 + community = environment.communities.find(params[:community_id])
  66 + return forbidden! unless current_person.can_post_content?(community)
  67 +
  68 + klass_type= params[:content_type].nil? ? 'TinyMceArticle' : params[:content_type]
  69 + return forbidden! unless ARTICLE_TYPES.include?(klass_type)
  70 +
  71 + article = klass_type.constantize.new(params[:article])
  72 + article.last_changed_by = current_person
  73 + article.created_by= current_person
  74 + article.profile = community
  75 +
  76 + if !article.save
  77 + render_api_errors!(article.errors.full_messages)
  78 + end
  79 + present article, :with => Entities::Article
  80 + end
  81 +
  82 + end
  83 + end
  84 +
  85 + end
  86 +
  87 + resource :people do
  88 + segment '/:person_id' do
  89 + resource :articles do
  90 + get do
  91 + person = environment.people.find(params[:person_id])
  92 + articles = select_filtered_collection_of(person, 'articles', params)
  93 + articles = articles.display_filter(current_person, person)
  94 + present articles, :with => Entities::Article
  95 + end
  96 +
  97 + get ':id' do
  98 + person = environment.people.find(params[:person_id])
  99 + article = find_article(person.articles, params[:id])
  100 + present article, :with => Entities::Article
  101 + end
  102 +
  103 + post do
  104 + person = environment.people.find(params[:person_id])
  105 + return forbidden! unless current_person.can_post_content?(person)
  106 +
  107 + klass_type= params[:content_type].nil? ? 'TinyMceArticle' : params[:content_type]
  108 + return forbidden! unless ARTICLE_TYPES.include?(klass_type)
  109 +
  110 + article = klass_type.constantize.new(params[:article])
  111 + article.last_changed_by = current_person
  112 + article.created_by= current_person
  113 + article.profile = person
  114 +
  115 + if !article.save
  116 + render_api_errors!(article.errors.full_messages)
  117 + end
  118 + present article, :with => Entities::Article
  119 + end
  120 +
  121 + end
  122 + end
  123 +
  124 + end
  125 +
  126 + resource :enterprises do
  127 + segment '/:enterprise_id' do
  128 + resource :articles do
  129 + get do
  130 + enterprise = environment.enterprises.find(params[:enterprise_id])
  131 + articles = select_filtered_collection_of(enterprise, 'articles', params)
  132 + articles = articles.display_filter(current_person, enterprise)
  133 + present articles, :with => Entities::Article
  134 + end
  135 +
  136 + get ':id' do
  137 + enterprise = environment.enterprises.find(params[:enterprise_id])
  138 + article = find_article(enterprise.articles, params[:id])
  139 + present article, :with => Entities::Article
  140 + end
  141 +
  142 + post do
  143 + enterprise = environment.enterprises.find(params[:enterprise_id])
  144 + return forbidden! unless current_person.can_post_content?(enterprise)
  145 +
  146 + klass_type= params[:content_type].nil? ? 'TinyMceArticle' : params[:content_type]
  147 + return forbidden! unless ARTICLE_TYPES.include?(klass_type)
  148 +
  149 + article = klass_type.constantize.new(params[:article])
  150 + article.last_changed_by = current_person
  151 + article.created_by= current_person
  152 + article.profile = enterprise
  153 +
  154 + if !article.save
  155 + render_api_errors!(article.errors.full_messages)
  156 + end
  157 + present article, :with => Entities::Article
  158 + end
  159 +
  160 + end
  161 + end
  162 +
  163 + end
  164 +
  165 +
  166 + end
  167 + end
  168 + end
  169 +end
lib/noosfero/api/v1/categories.rb 0 → 100644
@@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
  1 +module Noosfero
  2 + module API
  3 + module V1
  4 + class Categories < Grape::API
  5 + before { authenticate! }
  6 +
  7 + resource :categories do
  8 +
  9 + get do
  10 + type = params[:category_type]
  11 + categories = type.nil? ? environment.categories : environment.categories.find(:all, :conditions => {:type => type})
  12 + present categories, :with => Entities::Category
  13 + end
  14 +
  15 + desc "Return the category by id"
  16 + get ':id' do
  17 + present environment.categories.find(params[:id]), :with => Entities::Category
  18 + end
  19 +
  20 + end
  21 +
  22 + end
  23 + end
  24 + end
  25 +end
lib/noosfero/api/v1/comments.rb 0 → 100644
@@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
  1 +module Noosfero
  2 + module API
  3 + module V1
  4 + class Comments < Grape::API
  5 + before { authenticate! }
  6 +
  7 + resource :articles do
  8 + # Collect comments from articles
  9 + #
  10 + # Parameters:
  11 + # reference_id - comment id used as reference to collect comment
  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 /articles/12/comments?oldest&limit=10&reference_id=23
  17 + get ":id/comments" do
  18 +
  19 + conditions = make_conditions_with_parameter(params)
  20 + article = find_article(environment.articles, params[:id])
  21 +
  22 + if params[:reference_id]
  23 + comments = article.comments.send("#{params.key?(:oldest) ? 'older_than' : 'newer_than'}", params[:reference_id]).reorder("created_at DESC").find(:all, :conditions => conditions, :limit => limit)
  24 + else
  25 + comments = article.comments.reorder("created_at DESC").find(:all, :conditions => conditions, :limit => limit)
  26 + end
  27 + present comments, :with => Entities::Comment
  28 +
  29 + end
  30 +
  31 + get ":id/comments/:comment_id" do
  32 + article = find_article(environment.articles, params[:id])
  33 + present article.comments.find(params[:comment_id]), :with => Entities::Comment
  34 + end
  35 +
  36 + # Example Request:
  37 + # POST api/v1/articles/12/comments?private_toke=234298743290432&body=new comment
  38 + post ":id/comments" do
  39 + article = find_article(environment.articles, params[:id])
  40 + present article.comments.create(:author => current_person, :body => params[:body]), :with => Entities::Comment
  41 + end
  42 + end
  43 +
  44 + end
  45 + end
  46 + end
  47 +end
lib/noosfero/api/v1/communities.rb 0 → 100644
@@ -0,0 +1,72 @@ @@ -0,0 +1,72 @@
  1 +module Noosfero
  2 + module API
  3 + module V1
  4 + class Communities < Grape::API
  5 + before { authenticate! }
  6 +
  7 + resource :communities do
  8 +
  9 + # Collect comments from articles
  10 + #
  11 + # Parameters:
  12 + # from - date where the search will begin. If nothing is passed the default date will be the date of the first article created
  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 /communities?from=2013-04-04-14:41:43&until=2014-04-04-14:41:43&limit=10
  18 + # GET /communities?reference_id=10&limit=10&oldest
  19 + get do
  20 + communities = select_filtered_collection_of(environment, 'communities', params)
  21 + communities = communities.visible_for_person(current_person)
  22 + present communities, :with => Entities::Community
  23 + end
  24 +
  25 +
  26 + # Example Request:
  27 + # POST api/v1/communties?private_token=234298743290432&community[name]=some_name
  28 + post do
  29 + params[:community] ||= {}
  30 + begin
  31 + community = Community.create_after_moderation(current_person, params[:community].merge({:environment => environment}))
  32 + rescue
  33 + community = Community.new(params[:community])
  34 + end
  35 +
  36 + if !community.save
  37 + render_api_errors!(community.errors.full_messages)
  38 + end
  39 +
  40 + present community, :with => Entities::Community
  41 + end
  42 +
  43 + get ':id' do
  44 + community = environment.communities.visible.find_by_id(params[:id])
  45 + present community, :with => Entities::Community
  46 + end
  47 +
  48 + end
  49 +
  50 + resource :people do
  51 +
  52 + segment '/:person_id' do
  53 +
  54 + resource :communities do
  55 +
  56 + get do
  57 + person = environment.people.find(params[:person_id])
  58 + communities = select_filtered_collection_of(person, 'communities', params)
  59 + communities = communities.visible
  60 + present communities, :with => Entities::Community
  61 + end
  62 +
  63 + end
  64 +
  65 + end
  66 +
  67 + end
  68 +
  69 + end
  70 + end
  71 + end
  72 +end
lib/noosfero/api/v1/enterprises.rb 0 → 100644
@@ -0,0 +1,56 @@ @@ -0,0 +1,56 @@
  1 +module Noosfero
  2 + module API
  3 + module V1
  4 + class Enterprises < Grape::API
  5 + before { authenticate! }
  6 +
  7 + resource :enterprises do
  8 +
  9 + # Collect comments from articles
  10 + #
  11 + # Parameters:
  12 + # from - date where the search will begin. If nothing is passed the default date will be the date of the first article created
  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 /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_for_person(current_person)
  22 + present enterprises, :with => Entities::Enterprise
  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
  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
  43 + present enterprises, :with => Entities::Enterprise
  44 + end
  45 +
  46 + end
  47 +
  48 + end
  49 +
  50 + end
  51 +
  52 +
  53 + end
  54 + end
  55 + end
  56 +end
lib/noosfero/api/v1/people.rb 0 → 100644
@@ -0,0 +1,42 @@ @@ -0,0 +1,42 @@
  1 +module Noosfero
  2 + module API
  3 + module V1
  4 + class People < Grape::API
  5 + before { authenticate! }
  6 +
  7 + resource :people do
  8 +
  9 + # Collect comments from articles
  10 + #
  11 + # Parameters:
  12 + # from - date where the search will begin. If nothing is passed the default date will be the date of the first article created
  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 /people?from=2013-04-04-14:41:43&until=2014-04-04-14:41:43&limit=10
  18 + # GET /people?reference_id=10&limit=10&oldest
  19 + get do
  20 + people = select_filtered_collection_of(environment, 'people', params)
  21 + people = people.visible_for_person(current_person)
  22 + present people, :with => Entities::Person
  23 + end
  24 +
  25 + desc "Return the person information"
  26 + get ':id' do
  27 + person = environment.people.visible.find_by_id(params[:id])
  28 + present person, :with => Entities::Person
  29 + end
  30 +
  31 + desc "Return the person friends"
  32 + get ':id/friends' do
  33 + friends = current_person.friends.visible
  34 + present friends, :with => Entities::Person
  35 + end
  36 +
  37 + end
  38 +
  39 + end
  40 + end
  41 + end
  42 +end
lib/noosfero/api/v1/users.rb 0 → 100644
@@ -0,0 +1,48 @@ @@ -0,0 +1,48 @@
  1 +module Noosfero
  2 + module API
  3 + module V1
  4 + class Users < Grape::API
  5 + before { authenticate! }
  6 +
  7 + resource :users do
  8 +
  9 + #FIXME make the pagination
  10 + #FIXME put it on environment context
  11 + get do
  12 + present environment.users, :with => Entities::User
  13 + end
  14 +
  15 + # Example Request:
  16 + # POST api/v1/users?user[login]=some_login&user[password]=some
  17 + post do
  18 + user = User.new(params[:user])
  19 + user.terms_of_use = environment.terms_of_use
  20 + user.environment = environment
  21 + if !user.save
  22 + render_api_errors!(user.errors.full_messages)
  23 + end
  24 +
  25 + present user, :with => Entities::User
  26 + end
  27 +
  28 + get ":id" do
  29 + present environment.users.find_by_id(params[:id]), :with => Entities::User
  30 + end
  31 +
  32 + get ":id/permissions" do
  33 + user = environment.users.find(params[:id])
  34 + output = {}
  35 + user.person.role_assignments.map do |role_assigment|
  36 + if role_assigment.resource.respond_to?(:identifier) && role_assigment.resource.identifier == params[:profile]
  37 + output[:permissions] = role_assigment.role.permissions
  38 + end
  39 + end
  40 + present output
  41 + end
  42 +
  43 + end
  44 +
  45 + end
  46 + end
  47 + end
  48 +end
test/unit/api/helpers_test.rb
1 require File.dirname(__FILE__) + '/test_helper' 1 require File.dirname(__FILE__) + '/test_helper'
  2 +require File.expand_path(File.dirname(__FILE__) + "/../../../lib/noosfero/api/helpers")
2 3
3 class APITest < ActiveSupport::TestCase 4 class APITest < ActiveSupport::TestCase
4 5
5 - include API::APIHelpers 6 + include Noosfero::API::APIHelpers
6 7
7 should 'get the current user with valid token' do 8 should 'get the current user with valid token' do
8 user = create_user('someuser') 9 user = create_user('someuser')
test/unit/api/test_helper.rb
@@ -5,7 +5,7 @@ class ActiveSupport::TestCase @@ -5,7 +5,7 @@ class ActiveSupport::TestCase
5 include Rack::Test::Methods 5 include Rack::Test::Methods
6 6
7 def app 7 def app
8 - API::API 8 + Noosfero::API::API
9 end 9 end
10 10
11 def login_api 11 def login_api