Commit 09179b92d02743194294dc472e2953419ce1b25e

Authored by Alessandro Beltrão
Committed by Larissa Reis
1 parent 962b038c

Refactored api

app/api/app.rb
1 require_dependency 'api/helpers' 1 require_dependency 'api/helpers'
2 2
3 module Api 3 module Api
4 - class App < Grape::API 4 + class NoosferoFederation < Grape::API
5 use Rack::JSONP 5 use Rack::JSONP
  6 + helpers Helpers
  7 + before { detect_stuff_by_domain }
  8 + format :json
  9 + content_type :json, "application/jrd+json"
  10 + prefix [ENV['RAILS_RELATIVE_URL_ROOT'], ".well-known"].compact.join('/')
  11 + mount Federation::Webfinger
  12 + end
6 13
7 - logger = Logger.new(File.join(Rails.root, 'log', "#{ENV['RAILS_ENV'] || 'production'}_api.log"))  
8 - logger.formatter = GrapeLogging::Formatters::Default.new  
9 - #use GrapeLogging::Middleware::RequestLogger, { logger: logger }  
10 -  
11 - rescue_from :all do |e|  
12 - logger.error e  
13 - error! e.message, 500  
14 - end unless Rails.env.test?  
15 -  
16 - @@NOOSFERO_CONF = nil  
17 - def self.NOOSFERO_CONF  
18 - if @@NOOSFERO_CONF  
19 - @@NOOSFERO_CONF  
20 - else  
21 - file = Rails.root.join('config', 'noosfero.yml')  
22 - @@NOOSFERO_CONF = File.exists?(file) ? YAML.load_file(file)[Rails.env] || {} : {}  
23 - end  
24 - end  
25 - 14 + class BaseApi < Grape::API
26 before { set_locale } 15 before { set_locale }
27 before { setup_multitenancy } 16 before { setup_multitenancy }
28 before { detect_stuff_by_domain } 17 before { detect_stuff_by_domain }
@@ -54,7 +43,31 @@ module Api @@ -54,7 +43,31 @@ module Api
54 mount V1::Blocks 43 mount V1::Blocks
55 mount V1::Profiles 44 mount V1::Profiles
56 mount V1::Activities 45 mount V1::Activities
  46 + end
  47 +
  48 + class App < Grape::API
  49 + use Rack::JSONP
  50 +
  51 + logger = Logger.new(File.join(Rails.root, 'log', "#{ENV['RAILS_ENV'] || 'production'}_api.log"))
  52 + logger.formatter = GrapeLogging::Formatters::Default.new
  53 + #use GrapeLogging::Middleware::RequestLogger, { logger: logger }
57 54
  55 + rescue_from :all do |e|
  56 + logger.error e
  57 + error! e.message, 500
  58 + end unless Rails.env.test?
  59 +
  60 + @@NOOSFERO_CONF = nil
  61 + def self.NOOSFERO_CONF
  62 + if @@NOOSFERO_CONF
  63 + @@NOOSFERO_CONF
  64 + else
  65 + file = Rails.root.join('config', 'noosfero.yml')
  66 + @@NOOSFERO_CONF = File.exists?(file) ? YAML.load_file(file)[Rails.env] || {} : {}
  67 + end
  68 + end
  69 + mount BaseApi
  70 + mount NoosferoFederation
58 # hook point which allow plugins to add Grape::API extensions to Api::App 71 # hook point which allow plugins to add Grape::API extensions to Api::App
59 #finds for plugins which has api mount points classes defined (the class should extends Grape::API) 72 #finds for plugins which has api mount points classes defined (the class should extends Grape::API)
60 @plugins = Noosfero::Plugin.all.map { |p| p.constantize } 73 @plugins = Noosfero::Plugin.all.map { |p| p.constantize }
app/api/federation/webfinger.rb 0 → 100644
@@ -0,0 +1,88 @@ @@ -0,0 +1,88 @@
  1 +module Api
  2 + module Federation
  3 + class Webfinger < Grape::API
  4 + get 'webfinger' do
  5 + result = generate_jrd
  6 + present result, with: Grape::Presenters::Presenter
  7 + end
  8 + end
  9 + end
  10 +end
  11 +
  12 +def generate_jrd
  13 + unless valid_domain?
  14 + not_found!
  15 + Rails.logger.error 'Domain Not Found'
  16 + end
  17 + if request_acct?
  18 + acct_hash
  19 + elsif valid_uri?(params[:resource])
  20 + uri_hash
  21 + end
  22 +end
  23 +
  24 +def domain
  25 + if request_acct?
  26 + params[:resource].split('@')[1]
  27 + else
  28 + params[:resource].split('/')[2]
  29 + end
  30 +end
  31 +
  32 +def valid_domain?
  33 + environment.domains.map(&:name).include? domain
  34 +end
  35 +
  36 +def request_acct?
  37 + params[:resource].include? 'acct:'
  38 +end
  39 +
  40 +def acct_hash
  41 + acct = {}
  42 + acct[:subject] = params[:resource]
  43 + acct[:properties] = Person.find_by_identifier(extract_person_identifier)
  44 + if acct[:properties].nil?
  45 + Rails.logger.error 'Person not found'
  46 + not_found!
  47 + end
  48 + acct
  49 +end
  50 +
  51 +def extract_person_identifier
  52 + params[:resource].split('@')[0].split(':')[1]
  53 +end
  54 +
  55 +def valid_uri?(url)
  56 + uri = URI.parse(url)
  57 + if uri.is_a?(URI::HTTP)
  58 + true
  59 + else
  60 + Rails.logger.error 'Bad URI Error'
  61 + not_found!
  62 + end
  63 +end
  64 +
  65 +def uri_hash
  66 + uri = {}
  67 + uri[:subject] = params[:resource]
  68 + entity = find_entity(params[:resource])
  69 + id = params[:resource].split('/').last.to_i
  70 + begin
  71 + uri[:properties] = entity.classify.constantize.find(id)
  72 + rescue ActiveRecord::RecordNotFound
  73 + Rails.logger.error "Entity: #{entity} with id: #{id} not found"
  74 + not_found!
  75 + end
  76 + uri
  77 +end
  78 +
  79 +def find_entity(uri)
  80 + possible_entity = uri.split('/')
  81 + possible_entity.map! { |entity| "#{entity}s" }
  82 + entity = (ActiveRecord::Base.connection.tables & possible_entity).first
  83 + unless entity
  84 + Rails.logger.error 'Entity not found on records'
  85 + not_found!
  86 + end
  87 + entity
  88 +end
app/api/helpers.rb
@@ -415,7 +415,7 @@ module Api @@ -415,7 +415,7 @@ module Api
415 content_type == 'TextArticle' ? Article.text_article_types : content_type 415 content_type == 'TextArticle' ? Article.text_article_types : content_type
416 end 416 end
417 content_types.flatten.uniq 417 content_types.flatten.uniq
418 - end 418 + end
419 419
420 def period(from_date, until_date) 420 def period(from_date, until_date)
421 begin_period = from_date.nil? ? Time.at(0).to_datetime : from_date 421 begin_period = from_date.nil? ? Time.at(0).to_datetime : from_date
app/api/v1/activities.rb
1 module Api 1 module Api
2 module V1 2 module V1
3 class Activities < Grape::API 3 class Activities < Grape::API
4 - 4 +
5 resource :profiles do 5 resource :profiles do
6 6
7 get ':id/activities' do 7 get ':id/activities' do
@@ -9,7 +9,7 @@ module Api @@ -9,7 +9,7 @@ module Api
9 9
10 not_found! if profile.blank? || profile.secret || !profile.visible 10 not_found! if profile.blank? || profile.secret || !profile.visible
11 forbidden! if !profile.display_private_info_to?(current_person) 11 forbidden! if !profile.display_private_info_to?(current_person)
12 - 12 +
13 activities = profile.activities.map(&:activity) 13 activities = profile.activities.map(&:activity)
14 present activities, :with => Entities::Activity, :current_person => current_person 14 present activities, :with => Entities::Activity, :current_person => current_person
15 end 15 end
app/api/v1/articles.rb
@@ -62,9 +62,9 @@ module Api @@ -62,9 +62,9 @@ module Api
62 { :success => true } 62 { :success => true }
63 rescue Exception => exception 63 rescue Exception => exception
64 render_api_error!(_('The article couldn\'t be removed due to some problem. Please contact the administrator.'), 400) 64 render_api_error!(_('The article couldn\'t be removed due to some problem. Please contact the administrator.'), 400)
65 - end 65 + end
66 end 66 end
67 - 67 +
68 desc 'Report a abuse and/or violent content in a article by id' do 68 desc 'Report a abuse and/or violent content in a article by id' do
69 detail 'Submit a abuse (in general, a content violation) report about a specific article' 69 detail 'Submit a abuse (in general, a content violation) report about a specific article'
70 params Entities::Article.documentation 70 params Entities::Article.documentation
lib/noosfero/api/api.rb
@@ -1,106 +0,0 @@ @@ -1,106 +0,0 @@
1 -require 'grape'  
2 -#require 'rack/contrib'  
3 -Dir["#{Rails.root}/lib/noosfero/api/*.rb"].each {|file| require file unless file =~ /api\.rb/}  
4 -  
5 -module Noosfero  
6 - module API  
7 -  
8 - class NoosferoFederation < Grape::API  
9 - helpers APIHelpers  
10 - before { detect_stuff_by_domain }  
11 - format :json  
12 - content_type :json, "application/jrd+json"  
13 - prefix ".well-known"  
14 - mount Federation::Webfinger  
15 - end  
16 -  
17 - class BaseAPI < Grape::API  
18 - before { set_locale }  
19 - before { setup_multitenancy }  
20 - before { detect_stuff_by_domain }  
21 - before { filter_disabled_plugins_endpoints }  
22 - before { init_noosfero_plugins }  
23 - after { set_session_cookie }  
24 -  
25 - version 'v1'  
26 - prefix [ENV['RAILS_RELATIVE_URL_ROOT'], "api"].compact.join('/')  
27 - format :json  
28 - content_type :txt, "text/plain"  
29 -  
30 - mount V1::Articles  
31 - mount V1::Comments  
32 - mount V1::Users  
33 - mount V1::Communities  
34 - mount V1::People  
35 - mount V1::Enterprises  
36 - mount V1::Categories  
37 - mount V1::Tasks  
38 - mount V1::Tags  
39 - mount V1::Environments  
40 - mount V1::Search  
41 - mount V1::Contacts  
42 - mount V1::Boxes  
43 - mount V1::Profiles  
44 - mount V1::Activities  
45 - mount Session  
46 - end  
47 -  
48 - class API < Grape::API  
49 - use Rack::JSONP  
50 - helpers APIHelpers  
51 -  
52 - logger = Logger.new(File.join(Rails.root, 'log', "#{ENV['RAILS_ENV'] || 'production'}_api.log"))  
53 - logger.formatter = GrapeLogging::Formatters::Default.new  
54 - #use GrapeLogging::Middleware::RequestLogger, { logger: logger }  
55 -  
56 - rescue_from :all do |e|  
57 - logger.error e  
58 - error! e.message, 500  
59 - end  
60 -  
61 - @@NOOSFERO_CONF = nil  
62 - def self.NOOSFERO_CONF  
63 - if @@NOOSFERO_CONF  
64 - @@NOOSFERO_CONF  
65 - else  
66 - file = Rails.root.join('config', 'noosfero.yml')  
67 - @@NOOSFERO_CONF = File.exists?(file) ? YAML.load_file(file)[Rails.env] || {} : {}  
68 - end  
69 - end  
70 -  
71 - mount Noosfero::API::BaseAPI  
72 - mount Noosfero::API::NoosferoFederation  
73 -  
74 - # hook point which allow plugins to add Grape::API extensions to API::API  
75 - #finds for plugins which has api mount points classes defined (the class should extends Grape::API)  
76 - @plugins = Noosfero::Plugin.all.map { |p| p.constantize }  
77 - @plugins.each do |klass|  
78 - if klass.public_methods.include? :api_mount_points  
79 - klass.api_mount_points.each do |mount_class|  
80 - mount mount_class if mount_class && ( mount_class < Grape::API )  
81 - end  
82 - end  
83 - end  
84 -  
85 - def self.endpoint_unavailable?(endpoint, environment)  
86 - api_class = endpoint.options[:app] || endpoint.options[:for]  
87 - if api_class.present?  
88 - klass = api_class.name.deconstantize.constantize  
89 - return klass < Noosfero::Plugin && !environment.plugin_enabled?(klass)  
90 - end  
91 - end  
92 -  
93 - class << self  
94 - def endpoints_with_plugins(environment = nil)  
95 - if environment.present?  
96 - cloned_endpoints = endpoints_without_plugins.dup  
97 - cloned_endpoints.delete_if { |endpoint| endpoint_unavailable?(endpoint, environment) }  
98 - else  
99 - endpoints_without_plugins  
100 - end  
101 - end  
102 - alias_method_chain :endpoints, :plugins  
103 - end  
104 - end  
105 - end  
106 -end  
lib/noosfero/api/federation/webfinger.rb
@@ -1,91 +0,0 @@ @@ -1,91 +0,0 @@
1 -require 'active_support/inflector'  
2 -module Noosfero  
3 - module API  
4 - module Federation  
5 - class Webfinger < Grape::API  
6 - get 'webfinger' do  
7 - result = generate_jrd  
8 - present result, with: Grape::Presenters::Presenter  
9 - end  
10 - end  
11 - end  
12 - end  
13 -end  
14 -  
15 -def generate_jrd  
16 - unless valid_domain?  
17 - not_found!  
18 - Rails.logger.error 'Domain Not Found'  
19 - end  
20 - if request_acct?  
21 - acct_hash  
22 - elsif valid_uri?(params[:resource])  
23 - uri_hash  
24 - end  
25 -end  
26 -  
27 -def domain  
28 - if request_acct?  
29 - params[:resource].split('@')[1]  
30 - else  
31 - params[:resource].split('/')[2]  
32 - end  
33 -end  
34 -  
35 -def valid_domain?  
36 - environment.domains.map(&:name).include? domain  
37 -end  
38 -  
39 -def request_acct?  
40 - params[:resource].include? 'acct:'  
41 -end  
42 -  
43 -def acct_hash  
44 - acct = {}  
45 - acct[:subject] = params[:resource]  
46 - acct[:properties] = Person.find_by_identifier(extract_person_identifier)  
47 - if acct[:properties].nil?  
48 - Rails.logger.error 'Person not found'  
49 - not_found!  
50 - end  
51 - acct  
52 -end  
53 -  
54 -def extract_person_identifier  
55 - params[:resource].split('@')[0].split(':')[1]  
56 -end  
57 -  
58 -def valid_uri?(url)  
59 - uri = URI.parse(url)  
60 - if uri.is_a?(URI::HTTP)  
61 - true  
62 - else  
63 - Rails.logger.error 'Bad URI Error'  
64 - not_found!  
65 - end  
66 -end  
67 -  
68 -def uri_hash  
69 - uri = {}  
70 - uri[:subject] = params[:resource]  
71 - entity = find_entity(params[:resource])  
72 - id = params[:resource].split('/').last.to_i  
73 - begin  
74 - uri[:properties] = entity.classify.constantize.find(id)  
75 - rescue ActiveRecord::RecordNotFound  
76 - Rails.logger.error "Entity: #{entity} with id: #{id} not found"  
77 - not_found!  
78 - end  
79 - uri  
80 -end  
81 -  
82 -def find_entity(uri)  
83 - possible_entity = uri.split('/')  
84 - possible_entity.map! { |entity| "#{entity}s" }  
85 - entity = (ActiveRecord::Base.connection.tables & possible_entity).first  
86 - unless entity  
87 - Rails.logger.error 'Entity not found on records'  
88 - not_found!  
89 - end  
90 - entity  
91 -end