diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 323605e..61b2dbc 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -47,6 +47,11 @@ module API end end + def find_article(articles, id) + article = articles.find(id) + article.display_to?(current_user.person) ? article : forbidden! + end + def make_conditions_with_parameter(params = {}) conditions = {} from_date = DateTime.parse(params[:from]) if params[:from] @@ -64,9 +69,9 @@ module API conditions = make_conditions_with_parameter(params) if params[:reference_id] - objects = object.send(method).send("#{params.key?(:oldest) ? 'older_than' : 'newer_than'}", params[:reference_id]).find(:all, :conditions => conditions, :limit => limit, :order => "created_at DESC") + objects = object.send(method).send("#{params.key?(:oldest) ? 'older_than' : 'newer_than'}", params[:reference_id]).where(conditions).limit(limit).order("created_at DESC") else - objects = object.send(method).find(:all, :conditions => conditions, :limit => limit, :order => "created_at DESC") + objects = object.send(method).where(conditions).limit(limit).order("created_at DESC") end objects end diff --git a/lib/api/v1/articles.rb b/lib/api/v1/articles.rb index c8d3b88..c28dadc 100644 --- a/lib/api/v1/articles.rb +++ b/lib/api/v1/articles.rb @@ -19,30 +19,28 @@ module API # } get do articles = select_filtered_collection_of(environment, 'articles', params) + articles = articles.where(Article.display_filter(current_user.person, nil)[:conditions]) present articles, :with => Entities::Article end desc "Return the article id" get ':id' do - present environment.articles.find(params[:id]), :with => Entities::Article + article = find_article(environment.articles, params[:id]) + present article, :with => Entities::Article end get ':id/children' do - - conditions = make_conditions_with_parameter(params) - if params[:reference_id] - articles = environment.articles.find(params[:id]).children.send("#{params.key?(:oldest) ? 'older_than' : 'newer_than'}", params[:reference_id]).find(:all, :conditions => conditions, :limit => limit, :order => "created_at DESC") - else - articles = environment.articles.find(params[:id]).children.find(:all, :conditions => conditions, :limit => limit, :order => "created_at DESC") - end + article = find_article(environment.articles, params[:id]) + articles = select_filtered_collection_of(article, 'children', params) + articles = articles.where(Article.display_filter(current_user.person, nil)[:conditions]) present articles, :with => Entities::Article end get ':id/children/:child_id' do - present environment.articles.find(params[:id]).children.find(params[:child_id]), :with => Entities::Article + article = find_article(environment.articles, params[:id]) + present find_article(article.children, params[:child_id]), :with => Entities::Article end - end resource :communities do @@ -51,12 +49,14 @@ module API get do community = environment.communities.find(params[:community_id]) articles = select_filtered_collection_of(community, 'articles', params) + articles = articles.where(Article.display_filter(current_user.person, community)[:conditions]) present articles, :with => Entities::Article end get '/:id' do community = environment.communities.find(params[:community_id]) - present community.articles.find(params[:id]), :with => Entities::Article + article = find_article(community.articles, params[:id]) + present article, :with => Entities::Article end # Example Request: diff --git a/test/unit/api_test.rb b/test/unit/api_test.rb index e830308..3d31703 100644 --- a/test/unit/api_test.rb +++ b/test/unit/api_test.rb @@ -59,6 +59,16 @@ class APITest < ActiveSupport::TestCase assert_includes json["articles"].map { |a| a["id"] }, article.id end + should 'not list forbidden article when listing articles' do + person = fast_create(Person) + article = fast_create(Article, :profile_id => person.id, :name => "Some thing", :published => false) + assert !article.published? + + get "/api/v1/articles?#{params.to_query}" + json = JSON.parse(last_response.body) + assert_not_includes json['articles'].map {|a| a['id']}, article.id + end + should 'return article by id' do article = fast_create(Article, :profile_id => user.person.id, :name => "Some thing") get "/api/v1/articles/#{article.id}?#{params.to_query}" @@ -66,6 +76,15 @@ class APITest < ActiveSupport::TestCase assert_equal article.id, json["article"]["id"] end + should 'not return article if user has no permission to view it' do + person = fast_create(Person) + article = fast_create(Article, :profile_id => person.id, :name => "Some thing", :published => false) + assert !article.published? + + get "/api/v1/articles/#{article.id}?#{params.to_query}" + assert_equal 403, last_response.status + end + should 'return comments of an article' do article = fast_create(Article, :profile_id => user.person.id, :name => "Some thing") article.comments.create!(:body => "some comment", :author => user.person) @@ -104,4 +123,74 @@ class APITest < ActiveSupport::TestCase assert_equal category.name, json["category"]["name"] end + should 'return article by community' do + community = fast_create(Community) + article = fast_create(Article, :profile_id => community.id, :name => "Some thing") + get "/api/v1/communities/#{community.id}/articles/#{article.id}?#{params.to_query}" + json = JSON.parse(last_response.body) + assert_equal article.id, json["article"]["id"] + end + + should 'not return article by community if user has no permission to view it' do + community = fast_create(Community) + article = fast_create(Article, :profile_id => community.id, :name => "Some thing", :published => false) + assert !article.published? + + get "/api/v1/communities/#{community.id}/articles/#{article.id}?#{params.to_query}" + assert_equal 403, last_response.status + end + + should 'not list forbidden article when listing articles by community' do + community = fast_create(Community) + article = fast_create(Article, :profile_id => community.id, :name => "Some thing", :published => false) + assert !article.published? + + get "/api/v1/communities/#{community.id}/articles?#{params.to_query}" + json = JSON.parse(last_response.body) + assert_not_includes json['articles'].map {|a| a['id']}, article.id + end + + should 'list article children' do + article = fast_create(Article, :profile_id => user.person.id, :name => "Some thing") + child1 = fast_create(Article, :parent_id => article.id, :profile_id => user.person.id, :name => "Some thing") + child2 = fast_create(Article, :parent_id => article.id, :profile_id => user.person.id, :name => "Some thing") + get "/api/v1/articles/#{article.id}/children?#{params.to_query}" + json = JSON.parse(last_response.body) + assert_equivalent [child1.id, child2.id], json["articles"].map { |a| a["id"] } + end + + should 'not list children of forbidden article' do + person = fast_create(Person) + article = fast_create(Article, :profile_id => person.id, :name => "Some thing", :published => false) + child1 = fast_create(Article, :parent_id => article.id, :profile_id => person.id, :name => "Some thing") + child2 = fast_create(Article, :parent_id => article.id, :profile_id => person.id, :name => "Some thing") + get "/api/v1/articles/#{article.id}/children?#{params.to_query}" + assert_equal 403, last_response.status + end + + should 'not return child of forbidden article' do + person = fast_create(Person) + article = fast_create(Article, :profile_id => person.id, :name => "Some thing", :published => false) + child = fast_create(Article, :parent_id => article.id, :profile_id => person.id, :name => "Some thing") + get "/api/v1/articles/#{article.id}/children/#{child.id}?#{params.to_query}" + assert_equal 403, last_response.status + end + + should 'not return private child' do + person = fast_create(Person) + article = fast_create(Article, :profile_id => person.id, :name => "Some thing") + child = fast_create(Article, :parent_id => article.id, :profile_id => person.id, :name => "Some thing", :published => false) + get "/api/v1/articles/#{article.id}/children/#{child.id}?#{params.to_query}" + assert_equal 403, last_response.status + end + + should 'not list private child' do + person = fast_create(Person) + article = fast_create(Article, :profile_id => person.id, :name => "Some thing") + child = fast_create(Article, :parent_id => article.id, :profile_id => person.id, :name => "Some thing", :published => false) + get "/api/v1/articles/#{article.id}/children?#{params.to_query}" + json = JSON.parse(last_response.body) + assert_not_includes json['articles'].map {|a| a['id']}, child.id + end + end -- libgit2 0.21.2