Commit 108a4caa685fdeac9a60ad58687fd33a334a572b

Authored by Leandro Santos
Committed by Rodrigo Souto
1 parent b2ff80b5

api: refactoring api to put it at noosfero module

Rakefile
... ... @@ -26,7 +26,7 @@ plugins_tasks.each{ |ext| load ext }
26 26 desc "Print out grape routes"
27 27 task :grape_routes => :environment do
28 28 #require 'api/api.rb'
29   - API::API.routes.each do |route|
  29 + Noosfero::API::API.routes.each do |route|
30 30 puts route
31 31 method = route.route_method
32 32 path = route.route_path
... ...
config.ru
1 1 # This file is used by Rack-based servers to start the application.
2 2  
3 3 require ::File.expand_path('../config/environment', __FILE__)
4   -run Noosfero::Application
5   -require "config/environment"
6   -
7 4  
8 5 #use Rails::Rack::LogTailer
9 6 #use Rails::Rack::Static
... ... @@ -14,6 +11,6 @@ rails_app = Rack::Builder.new do
14 11 end
15 12  
16 13 run Rack::Cascade.new([
17   - API::API,
  14 + Noosfero::API::API,
18 15 rails_app
19 16 ])
... ...
lib/api/api.rb
... ... @@ -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   -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   -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   -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   -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   -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   -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   -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   -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   -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   -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 @@
  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 @@
  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 @@
  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 @@
  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 @@
  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 @@
  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 @@
  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 @@
  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 @@
  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 @@
  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 @@
  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 1 require File.dirname(__FILE__) + '/test_helper'
  2 +require File.expand_path(File.dirname(__FILE__) + "/../../../lib/noosfero/api/helpers")
2 3  
3 4 class APITest < ActiveSupport::TestCase
4 5  
5   - include API::APIHelpers
  6 + include Noosfero::API::APIHelpers
6 7  
7 8 should 'get the current user with valid token' do
8 9 user = create_user('someuser')
... ...
test/unit/api/test_helper.rb
... ... @@ -5,7 +5,7 @@ class ActiveSupport::TestCase
5 5 include Rack::Test::Methods
6 6  
7 7 def app
8   - API::API
  8 + Noosfero::API::API
9 9 end
10 10  
11 11 def login_api
... ...