Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fix receiving post notifications with attachments

refs #53
  • Loading branch information...
commit c9a6e61fb62b4d23bedb8bdceb3bd515f2a93968 1 parent b843142
Jesse Stuart jvatic authored
Showing with 81 additions and 24 deletions.
  1. +28 −1 lib/tentd/api/posts.rb
  2. +53 −23 spec/integration/api/posts_spec.rb
29 lib/tentd/api/posts.rb
View
@@ -343,6 +343,31 @@ def action(env)
end
end
+ class CreatePlaceholderAttachments < Middleware
+ def action(env)
+ return env unless env.params.data.attachments.kind_of?(Array) && env.response && !env.params.attachments
+ post = env.response
+ version = post.latest_version(:fields => [:id])
+ env.params.data.attachments.each do |attachment|
+ a = Model::PostAttachment.create(
+ :post => post,
+ :type => attachment.type,
+ :category => attachment.category.to_s,
+ :name => attachment.name,
+ :data => '',
+ :size => attachment[:size]
+ )
+
+ a.db[:post_versions_attachments].insert(
+ :post_attachment_id => a.id,
+ :post_version_id => version.id
+ )
+ end
+ env.response.reload
+ env
+ end
+ end
+
class Notify < Middleware
def action(env)
return env if authorize_env?(env, :write_posts) && env.params.data && env.params.data.id && env.current_auth.kind_of?(Model::AppAuthorization)
@@ -376,7 +401,7 @@ def action(env)
if following = Model::Following.first(:id => post.following_id)
client = TentClient.new(following.core_profile.servers.first, following.auth_details.merge(:skip_serialization => true, :faraday_adapter => TentD.faraday_adapter))
res = client.post.attachment.get(post.public_id, env.params.attachment_name, type)
- return [res.status, res.headers, res.body]
+ return [res.status, res.headers, [res.body]]
else
raise NotFound
end
@@ -538,12 +563,14 @@ def action(env)
post '/posts' do |b|
b.use CreatePost
b.use CreateAttachments
+ b.use CreatePlaceholderAttachments
b.use Notify
end
post '/notifications/:following_id' do |b|
b.use CreatePost
b.use CreateAttachments
+ b.use CreatePlaceholderAttachments
b.use Notify
b.use TriggerUpdates
end
76 spec/integration/api/posts_spec.rb
View
@@ -1343,34 +1343,64 @@ def authorize!(*scopes)
end
end
- context 'as follower' do
- before { authorize!(:entity => 'https://smith.example.com') }
+ context 'as follow' do
+ let(:entity) { 'https://smith.example.com' }
+ let(:follower) { Fabricate(:follower, :entity => entity) }
+ let(:following) { Fabricate(:following, :entity => entity) }
+ before { authorize!(:entity => entity) }
let(:post_attributes) {
p.attributes.merge(:id => rand(36 ** 6).to_s(36), :type => p.type.uri)
}
- it 'should allow a post from the follower' do
- json_post "/posts", post_attributes, env
- body = JSON.parse(last_response.body)
- post = TentD::Model::Post.order(:id.asc).last
- expect(body['id']).to eq(post.public_id)
- expect(post.public_id).to eq(post_attributes[:id])
- end
+ [:follower, :following].each do |follow_type|
+ it "should allow a post from #{follow_type}" do
+ follow = send(follow_type)
+ env['current_auth'] = follow
- it "should silently allow a duplicate post from a follower" do
- json_post "/posts", post_attributes, env
- expect(last_response.status).to eq(200)
- json_post "/posts", post_attributes, env
- expect(last_response.status).to eq(200)
- end
+ json_post "/posts", post_attributes, env
+ body = JSON.parse(last_response.body)
+ post = TentD::Model::Post.order(:id.asc).last
+ expect(body['id']).to eq(post.public_id)
+ expect(post.public_id).to eq(post_attributes[:id])
+ end
- it "should not allow a post that isn't from the follower" do
- post_attributes = p.attributes
- post_attributes.delete(:id)
- post_attributes[:type] = p.type.uri
- json_post "/posts", post_attributes.merge(:entity => 'example.org'), env
- expect(last_response.status).to eq(403)
- expect(Yajl::Parser.parse(last_response.body)).to eql({ 'error' => 'Unauthorized' })
+ it "should accept attachments from #{follow_type}" do
+ post_attributes[:attachments] = [{ :size => 12, :name => 'foo.txt', :type => 'text/plain', :category => 'foo' }]
+ expect(lambda {
+ expect(lambda {
+ expect(lambda {
+ json_post('/posts', post_attributes, env)
+ }).to change(TentD::Model::Post, :count).by(1)
+ }).to change(TentD::Model::PostVersion, :count).by(1)
+ }).to change(TentD::Model::PostAttachment, :count).by(1)
+ body = JSON.parse(last_response.body)
+ post = TentD::Model::Post.order(:id.desc).first
+ expect(body['id']).to eq(post.public_id)
+ expect(post.attachments.map(&:id)).to eq(post.latest_version.attachments.map(&:id))
+ expect(post.attachments.map(&:size)).to eq([12])
+ end
+
+ it "should silently allow a duplicate post from a #{follow_type}" do
+ follow = send(follow_type)
+ env['current_auth'] = follow
+
+ json_post "/posts", post_attributes, env
+ expect(last_response.status).to eq(200)
+ json_post "/posts", post_attributes, env
+ expect(last_response.status).to eq(200)
+ end
+
+ it "should not allow a post that isn't from the #{follow_type}" do
+ follow = send(follow_type)
+ env['current_auth'] = follow
+
+ post_attributes = p.attributes
+ post_attributes.delete(:id)
+ post_attributes[:type] = p.type.uri
+ json_post "/posts", post_attributes.merge(:entity => 'example.org'), env
+ expect(last_response.status).to eq(403)
+ expect(Yajl::Parser.parse(last_response.body)).to eql({ 'error' => 'Unauthorized' })
+ end
end
it "should notify subscribed apps of post" do
@@ -1665,7 +1695,7 @@ def authorize!(*scopes)
it 'should get attachment via proxy' do
http_stubs.get("/posts/#{post.public_id}/attachments/foo") { |env|
expect(env[:request_headers]['Authorization']).to match(/#{following.mac_key_id}/)
- [200, { 'Content-Type' => attachment.type }, [Base64.decode64(attachment.data)]]
+ [200, { 'Content-Type' => attachment.type }, Base64.decode64(attachment.data)]
}
json_get("/posts/#{post.public_id}/attachments/foo", {}, env)
expect(last_response.status).to eql(200)
Please sign in to comment.
Something went wrong with that request. Please try again.