From 09179b92d02743194294dc472e2953419ce1b25e Mon Sep 17 00:00:00 2001 From: Alessandro Caetano Date: Mon, 30 May 2016 10:18:23 -0400 Subject: [PATCH] Refactored api --- app/api/app.rb | 53 +++++++++++++++++++++++++++++++++-------------------- app/api/federation/webfinger.rb | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ app/api/helpers.rb | 2 +- app/api/v1/activities.rb | 4 ++-- app/api/v1/articles.rb | 4 ++-- lib/noosfero/api/api.rb | 106 ---------------------------------------------------------------------------------------------------------- lib/noosfero/api/federation/webfinger.rb | 91 ------------------------------------------------------------------------------------------- 7 files changed, 126 insertions(+), 222 deletions(-) create mode 100644 app/api/federation/webfinger.rb delete mode 100644 lib/noosfero/api/api.rb delete mode 100644 lib/noosfero/api/federation/webfinger.rb diff --git a/app/api/app.rb b/app/api/app.rb index a78124a..e6cb3f1 100644 --- a/app/api/app.rb +++ b/app/api/app.rb @@ -1,28 +1,17 @@ require_dependency 'api/helpers' module Api - class App < Grape::API + class NoosferoFederation < Grape::API use Rack::JSONP + helpers Helpers + before { detect_stuff_by_domain } + format :json + content_type :json, "application/jrd+json" + prefix [ENV['RAILS_RELATIVE_URL_ROOT'], ".well-known"].compact.join('/') + mount Federation::Webfinger + end - logger = Logger.new(File.join(Rails.root, 'log', "#{ENV['RAILS_ENV'] || 'production'}_api.log")) - logger.formatter = GrapeLogging::Formatters::Default.new - #use GrapeLogging::Middleware::RequestLogger, { logger: logger } - - rescue_from :all do |e| - logger.error e - error! e.message, 500 - end unless Rails.env.test? - - @@NOOSFERO_CONF = nil - def self.NOOSFERO_CONF - if @@NOOSFERO_CONF - @@NOOSFERO_CONF - else - file = Rails.root.join('config', 'noosfero.yml') - @@NOOSFERO_CONF = File.exists?(file) ? YAML.load_file(file)[Rails.env] || {} : {} - end - end - + class BaseApi < Grape::API before { set_locale } before { setup_multitenancy } before { detect_stuff_by_domain } @@ -54,7 +43,31 @@ module Api mount V1::Blocks mount V1::Profiles mount V1::Activities + end + + class App < Grape::API + use Rack::JSONP + + logger = Logger.new(File.join(Rails.root, 'log', "#{ENV['RAILS_ENV'] || 'production'}_api.log")) + logger.formatter = GrapeLogging::Formatters::Default.new + #use GrapeLogging::Middleware::RequestLogger, { logger: logger } + rescue_from :all do |e| + logger.error e + error! e.message, 500 + end unless Rails.env.test? + + @@NOOSFERO_CONF = nil + def self.NOOSFERO_CONF + if @@NOOSFERO_CONF + @@NOOSFERO_CONF + else + file = Rails.root.join('config', 'noosfero.yml') + @@NOOSFERO_CONF = File.exists?(file) ? YAML.load_file(file)[Rails.env] || {} : {} + end + end + mount BaseApi + mount NoosferoFederation # hook point which allow plugins to add Grape::API extensions to Api::App #finds for plugins which has api mount points classes defined (the class should extends Grape::API) @plugins = Noosfero::Plugin.all.map { |p| p.constantize } diff --git a/app/api/federation/webfinger.rb b/app/api/federation/webfinger.rb new file mode 100644 index 0000000..98b1a1b --- /dev/null +++ b/app/api/federation/webfinger.rb @@ -0,0 +1,88 @@ +module Api + module Federation + class Webfinger < Grape::API + get 'webfinger' do + result = generate_jrd + present result, with: Grape::Presenters::Presenter + end + end + end +end + +def generate_jrd + unless valid_domain? + not_found! + Rails.logger.error 'Domain Not Found' + end + if request_acct? + acct_hash + elsif valid_uri?(params[:resource]) + uri_hash + end +end + +def domain + if request_acct? + params[:resource].split('@')[1] + else + params[:resource].split('/')[2] + end +end + +def valid_domain? + environment.domains.map(&:name).include? domain +end + +def request_acct? + params[:resource].include? 'acct:' +end + +def acct_hash + acct = {} + acct[:subject] = params[:resource] + acct[:properties] = Person.find_by_identifier(extract_person_identifier) + if acct[:properties].nil? + Rails.logger.error 'Person not found' + not_found! + end + acct +end + +def extract_person_identifier + params[:resource].split('@')[0].split(':')[1] +end + +def valid_uri?(url) + uri = URI.parse(url) + if uri.is_a?(URI::HTTP) + true + else + Rails.logger.error 'Bad URI Error' + not_found! + end +end + +def uri_hash + uri = {} + uri[:subject] = params[:resource] + entity = find_entity(params[:resource]) + id = params[:resource].split('/').last.to_i + begin + uri[:properties] = entity.classify.constantize.find(id) + rescue ActiveRecord::RecordNotFound + Rails.logger.error "Entity: #{entity} with id: #{id} not found" + not_found! + end + uri +end + +def find_entity(uri) + possible_entity = uri.split('/') + possible_entity.map! { |entity| "#{entity}s" } + entity = (ActiveRecord::Base.connection.tables & possible_entity).first + unless entity + Rails.logger.error 'Entity not found on records' + not_found! + end + entity +end diff --git a/app/api/helpers.rb b/app/api/helpers.rb index 1e39131..b6b15ea 100644 --- a/app/api/helpers.rb +++ b/app/api/helpers.rb @@ -415,7 +415,7 @@ module Api content_type == 'TextArticle' ? Article.text_article_types : content_type end content_types.flatten.uniq - end + end def period(from_date, until_date) begin_period = from_date.nil? ? Time.at(0).to_datetime : from_date diff --git a/app/api/v1/activities.rb b/app/api/v1/activities.rb index e29245b..494c9b1 100644 --- a/app/api/v1/activities.rb +++ b/app/api/v1/activities.rb @@ -1,7 +1,7 @@ module Api module V1 class Activities < Grape::API - + resource :profiles do get ':id/activities' do @@ -9,7 +9,7 @@ module Api not_found! if profile.blank? || profile.secret || !profile.visible forbidden! if !profile.display_private_info_to?(current_person) - + activities = profile.activities.map(&:activity) present activities, :with => Entities::Activity, :current_person => current_person end diff --git a/app/api/v1/articles.rb b/app/api/v1/articles.rb index 5585b50..cc24eac 100644 --- a/app/api/v1/articles.rb +++ b/app/api/v1/articles.rb @@ -62,9 +62,9 @@ module Api { :success => true } rescue Exception => exception render_api_error!(_('The article couldn\'t be removed due to some problem. Please contact the administrator.'), 400) - end + end end - + desc 'Report a abuse and/or violent content in a article by id' do detail 'Submit a abuse (in general, a content violation) report about a specific article' params Entities::Article.documentation diff --git a/lib/noosfero/api/api.rb b/lib/noosfero/api/api.rb deleted file mode 100644 index 4966f0b..0000000 --- a/lib/noosfero/api/api.rb +++ /dev/null @@ -1,106 +0,0 @@ -require 'grape' -#require 'rack/contrib' -Dir["#{Rails.root}/lib/noosfero/api/*.rb"].each {|file| require file unless file =~ /api\.rb/} - -module Noosfero - module API - - class NoosferoFederation < Grape::API - helpers APIHelpers - before { detect_stuff_by_domain } - format :json - content_type :json, "application/jrd+json" - prefix ".well-known" - mount Federation::Webfinger - end - - class BaseAPI < Grape::API - before { set_locale } - before { setup_multitenancy } - before { detect_stuff_by_domain } - before { filter_disabled_plugins_endpoints } - before { init_noosfero_plugins } - after { set_session_cookie } - - version 'v1' - prefix [ENV['RAILS_RELATIVE_URL_ROOT'], "api"].compact.join('/') - format :json - content_type :txt, "text/plain" - - mount V1::Articles - mount V1::Comments - mount V1::Users - mount V1::Communities - mount V1::People - mount V1::Enterprises - mount V1::Categories - mount V1::Tasks - mount V1::Tags - mount V1::Environments - mount V1::Search - mount V1::Contacts - mount V1::Boxes - mount V1::Profiles - mount V1::Activities - mount Session - end - - class API < Grape::API - use Rack::JSONP - helpers APIHelpers - - logger = Logger.new(File.join(Rails.root, 'log', "#{ENV['RAILS_ENV'] || 'production'}_api.log")) - logger.formatter = GrapeLogging::Formatters::Default.new - #use GrapeLogging::Middleware::RequestLogger, { logger: logger } - - rescue_from :all do |e| - logger.error e - error! e.message, 500 - end - - @@NOOSFERO_CONF = nil - def self.NOOSFERO_CONF - if @@NOOSFERO_CONF - @@NOOSFERO_CONF - else - file = Rails.root.join('config', 'noosfero.yml') - @@NOOSFERO_CONF = File.exists?(file) ? YAML.load_file(file)[Rails.env] || {} : {} - end - end - - mount Noosfero::API::BaseAPI - mount Noosfero::API::NoosferoFederation - - # hook point which allow plugins to add Grape::API extensions to API::API - #finds for plugins which has api mount points classes defined (the class should extends Grape::API) - @plugins = Noosfero::Plugin.all.map { |p| p.constantize } - @plugins.each do |klass| - if klass.public_methods.include? :api_mount_points - klass.api_mount_points.each do |mount_class| - mount mount_class if mount_class && ( mount_class < Grape::API ) - end - end - end - - def self.endpoint_unavailable?(endpoint, environment) - api_class = endpoint.options[:app] || endpoint.options[:for] - if api_class.present? - klass = api_class.name.deconstantize.constantize - return klass < Noosfero::Plugin && !environment.plugin_enabled?(klass) - end - end - - class << self - def endpoints_with_plugins(environment = nil) - if environment.present? - cloned_endpoints = endpoints_without_plugins.dup - cloned_endpoints.delete_if { |endpoint| endpoint_unavailable?(endpoint, environment) } - else - endpoints_without_plugins - end - end - alias_method_chain :endpoints, :plugins - end - end - end -end diff --git a/lib/noosfero/api/federation/webfinger.rb b/lib/noosfero/api/federation/webfinger.rb deleted file mode 100644 index 8dc4bd0..0000000 --- a/lib/noosfero/api/federation/webfinger.rb +++ /dev/null @@ -1,91 +0,0 @@ -require 'active_support/inflector' -module Noosfero - module API - module Federation - class Webfinger < Grape::API - get 'webfinger' do - result = generate_jrd - present result, with: Grape::Presenters::Presenter - end - end - end - end -end - -def generate_jrd - unless valid_domain? - not_found! - Rails.logger.error 'Domain Not Found' - end - if request_acct? - acct_hash - elsif valid_uri?(params[:resource]) - uri_hash - end -end - -def domain - if request_acct? - params[:resource].split('@')[1] - else - params[:resource].split('/')[2] - end -end - -def valid_domain? - environment.domains.map(&:name).include? domain -end - -def request_acct? - params[:resource].include? 'acct:' -end - -def acct_hash - acct = {} - acct[:subject] = params[:resource] - acct[:properties] = Person.find_by_identifier(extract_person_identifier) - if acct[:properties].nil? - Rails.logger.error 'Person not found' - not_found! - end - acct -end - -def extract_person_identifier - params[:resource].split('@')[0].split(':')[1] -end - -def valid_uri?(url) - uri = URI.parse(url) - if uri.is_a?(URI::HTTP) - true - else - Rails.logger.error 'Bad URI Error' - not_found! - end -end - -def uri_hash - uri = {} - uri[:subject] = params[:resource] - entity = find_entity(params[:resource]) - id = params[:resource].split('/').last.to_i - begin - uri[:properties] = entity.classify.constantize.find(id) - rescue ActiveRecord::RecordNotFound - Rails.logger.error "Entity: #{entity} with id: #{id} not found" - not_found! - end - uri -end - -def find_entity(uri) - possible_entity = uri.split('/') - possible_entity.map! { |entity| "#{entity}s" } - entity = (ActiveRecord::Base.connection.tables & possible_entity).first - unless entity - Rails.logger.error 'Entity not found on records' - not_found! - end - entity -end -- libgit2 0.21.2