From 8246882067642f960c2f9092c02b50c695c8cb0b Mon Sep 17 00:00:00 2001 From: zhitomirskiyi Date: Wed, 3 Nov 2010 16:42:33 -0700 Subject: [PATCH] MS IZ fixed some permissions in photo controller --- app/controllers/photos_controller.rb | 96 ++++++++++++---------- lib/diaspora/user/querying.rb | 4 + spec/controllers/photos_controller_spec.rb | 44 ++++++++-- spec/models/user/querying_spec.rb | 38 +++++++-- 4 files changed, 126 insertions(+), 56 deletions(-) diff --git a/app/controllers/photos_controller.rb b/app/controllers/photos_controller.rb index ebeaa9e18..51fcf13a5 100644 --- a/app/controllers/photos_controller.rb +++ b/app/controllers/photos_controller.rb @@ -24,35 +24,14 @@ class PhotosController < ApplicationController album = current_user.find_visible_post_by_id( params[:photo][:album_id] ) begin - - ######################## dealing with local files ############# - # get file name - file_name = params[:qqfile] - # get file content type - att_content_type = (request.content_type.to_s == "") ? "application/octet-stream" : request.content_type.to_s - # create temporal file - begin - file = Tempfile.new(file_name, {:encoding => 'BINARY'}) - file.print request.raw_post.force_encoding('BINARY') - rescue RuntimeError => e - raise e unless e.message.include?('cannot generate tempfile') - file = Tempfile.new(file_name) # Ruby 1.8 compatibility - file.print request.raw_post - end - # put data into this file from raw post request - - # create several required methods for this temporal file - Tempfile.send(:define_method, "content_type") {return att_content_type} - Tempfile.send(:define_method, "original_filename") {return file_name} - - ############## - - params[:photo][:user_file] = file + params[:photo][:user_file] = file_handler(params) @photo = current_user.build_post(:photo, params[:photo]) if @photo.save - raise 'MongoMapper failed to catch a failed save' unless post.id + raise 'MongoMapper failed to catch a failed save' unless @photo.id + + current_user.dispatch_post(@photo, :to => params[:photo][:to]) respond_to do |format| format.json{render(:layout => false , :json => {"success" => true, "data" => @photo}.to_json )} @@ -83,15 +62,17 @@ class PhotosController < ApplicationController end def destroy - @photo = current_user.find_visible_post_by_id params[:id] + photo = current_user.my_posts.where(:_id => params[:id]).first - @photo.destroy - flash[:notice] = I18n.t 'photos.destroy.notice' + if photo + photo.destroy + flash[:notice] = I18n.t 'photos.destroy.notice' + + redirect = photo.album + end - redirect = @photo.album redirect ||= photos_path - - respond_with :location => @photo.album + respond_with :location => redirect end def show @@ -107,21 +88,52 @@ class PhotosController < ApplicationController end def edit - @photo = current_user.find_visible_post_by_id params[:id] - @album = @photo.album - - redirect_to @photo #unless current_user.owns? @photo + @photo = current_user.my_posts.where(:_id => params[:id]).first + if @photo + @album = @photo.album + else + redirect_to photos_path + end end def update - @photo = current_user.find_visible_post_by_id params[:id] - - if current_user.update_post( @photo, params[:photo] ) - flash[:notice] = I18n.t 'photos.update.notice' - respond_with @photo + photo = current_user.my_posts.where(:_id => params[:id]).first + if photo + if current_user.update_post( photo, params[:photo] ) + flash[:notice] = I18n.t 'photos.update.notice' + respond_with photo + else + flash[:error] = I18n.t 'photos.update.error' + redirect_to [:edit, photo] + end else - flash[:error] = I18n.t 'photos.update.error' - redirect_to [:edit, @photo] + redirect_to photos_path end end + + + private + + def file_handler(params) + ######################## dealing with local files ############# + # get file name + file_name = params[:qqfile] + # get file content type + att_content_type = (request.content_type.to_s == "") ? "application/octet-stream" : request.content_type.to_s + # create tempora##l file + begin + file = Tempfile.new(file_name, {:encoding => 'BINARY'}) + file.print request.raw_post.force_encoding('BINARY') + rescue RuntimeError => e + raise e unless e.message.include?('cannot generate tempfile') + file = Tempfile.new(file_name) # Ruby 1.8 compatibility + file.print request.raw_post + end + # put data into this file from raw post request + + # create several required methods for this temporal file + Tempfile.send(:define_method, "content_type") {return att_content_type} + Tempfile.send(:define_method, "original_filename") {return file_name} + file + end end diff --git a/lib/diaspora/user/querying.rb b/lib/diaspora/user/querying.rb index 0b7e4276b..3121c491a 100644 --- a/lib/diaspora/user/querying.rb +++ b/lib/diaspora/user/querying.rb @@ -32,6 +32,10 @@ module Diaspora end end + def my_posts + Post.where(:diaspora_handle => person.diaspora_handle) + end + def contact_for(person) id = person.id contact_for_person_id(id) diff --git a/spec/controllers/photos_controller_spec.rb b/spec/controllers/photos_controller_spec.rb index 5f052288e..7f87b31d9 100644 --- a/spec/controllers/photos_controller_spec.rb +++ b/spec/controllers/photos_controller_spec.rb @@ -8,31 +8,44 @@ describe PhotosController do let(:user) {make_user} let(:user2) {make_user} - let(:aspect) {user.aspects.create(:name => 'winners')} + let!(:aspect) {user.aspects.create(:name => 'winners')} let(:aspect2) {user2.aspects.create(:name => 'winners')} let!(:album) {user.post(:album, :to => aspect.id, :name => "room on fire")} + let!(:album2) {user2.post(:album, :to => aspect2.id, :name => "room on fire")} let(:filename) {'button.png'} let(:fixture_name) {File.join(File.dirname(__FILE__), '..', 'fixtures', filename)} let(:image) {File.open(fixture_name)} let!(:photo){ user.post(:photo, :album_id => album.id, :user_file => image, :to => aspect.id)} let(:photo_no_album){ user.post(:photo, :user_file => image, :to => aspect.id)} + let!(:photo2){ user2.post(:photo, :album_id => album2.id, :user_file => image, :to => aspect2.id)} before do friend_users(user, aspect, user2, aspect2) sign_in :user, user user.reload + aspect.reload + aspect2.reload @controller.stub!(:current_user).and_return(user) end describe '#create' do + let(:foo) {{:album_id => album.id.to_s}} + + before do + @controller.stub!(:file_handler).and_return(image) + end it 'can make a photo in an album' do - pending + proc{ post :create, :photo => foo, :qqfile => fixture_name }.should change(Photo, :count).by(1) end it 'can make a picture without an album' do pending end + + it 'does not let you create a photo in an album you do not own' do + pending + end end describe '#index' do @@ -71,23 +84,32 @@ describe PhotosController do describe '#edit' do it 'should let you edit a photo with an album' do - pending - get :edit, :id => photo.id - response.should_not redirect_to(photo) + response.code.should == "200" end it 'should let you edit a photo you own that does not have an album' do - pending - get :edit, :id => photo_no_album.id - response.should_not redirect_to(photo) + response.code.should == "200" + end + + it 'should not let you edit a photo that is not yours' do + get :edit, :id => photo2.id + response.should redirect_to(:action => :index) end end describe '#destroy' do + it 'should let me delete my photos' do + delete :destroy, :id => photo.id + Photo.find_by_id(photo.id).should be nil + end + it 'will not let you destory posts you do not own' do + delete :destroy, :id => photo2.id + Photo.find_by_id(photo2.id).should_not be nil + end end describe "#update" do @@ -102,5 +124,11 @@ describe PhotosController do put :update, :id => photo.id, :photo => params photo.reload.person_id.should == user.person.id end + + it 'should redirect if you do not have access to the post' do + params = { :caption => "now with lasers!"} + put :update, :id => photo2.id, :photo => params + response.should redirect_to(:action => :index) + end end end diff --git a/spec/models/user/querying_spec.rb b/spec/models/user/querying_spec.rb index 0fddade8f..e9ed00448 100644 --- a/spec/models/user/querying_spec.rb +++ b/spec/models/user/querying_spec.rb @@ -7,19 +7,22 @@ require 'spec_helper' describe User do let(:user) {make_user} + let!(:aspect) { user.aspects.create(:name => "cats")} let!(:user2) { Factory(:user_with_aspect) } let(:person_one) { Factory.create :person } let(:person_two) { Factory.create :person } let(:person_three) { Factory.create :person } - + context 'with two posts' do let!(:status_message1) { user2.post :status_message, :message => "hi", :to => user2.aspects.first.id } let!(:status_message2) { user2.post :status_message, :message => "hey", :public => true , :to => user2.aspects.first.id } - - - describe "#visible_posts" do + let!(:status_message4) { user2.post :status_message, :message => "blah", :public => true , :to => user2.aspects.first.id } + let!(:status_message3) { user.post :status_message, :message => "hey", :public => true , :to => user.aspects.first.id } + + + describe "#visible_posts" do it "queries by person id" do query = user2.visible_posts(:person_id => user2.person.id) query.include?(status_message1).should == true @@ -59,6 +62,29 @@ describe User do end end end + + describe '#my_posts' do + it 'should return only my posts' do + posts2 = user2.my_posts + posts2.should include status_message1 + posts2.should include status_message2 + posts2.should_not include status_message3 + user.my_posts.should include status_message3 + end + + it 'returns query objexts so chainable' do + user2.my_posts.where(:_id => status_message1.id.to_s).all.should == [status_message1] + + pub_posts = user2.my_posts.where(:public => true).all + + pub_posts.should_not include status_message1 + pub_posts.should include status_message2 + pub_posts.should include status_message4 + pub_posts.should_not include status_message3 + + user.my_posts.where(:public => false).all.should == [] + end + end end context 'with two users' do @@ -68,8 +94,8 @@ describe User do let!(:user4) { Factory.create(:user_with_aspect)} before do - friend_users(user, first_aspect, user4, user4.aspects.first) - friend_users(user, second_aspect, user2, user2.aspects.first) + friend_users(user, first_aspect, user4, user4.aspects.first) + friend_users(user, second_aspect, user2, user2.aspects.first) end describe '#friends_not_in_aspect' do